1.将 str 转换成 Timestamp
new_time = pd.to_datetime('2019-01-01 00:51:00')
new_time
Our[1]: Timestamp('2019-01-01 00:51:00')
所以如果要将dataframe中的一列全转换成Timestamp类型,可以这样:
data['valid_time_gmt'] = data['valid_time_gmt'].apply(lambda x:pd.to_datetime(x))
或者
data['valid_time_gmt'] = pd.to_datetime(data['valid_time_gmt'])
此外,将字符串转换成时间戳格式之后,可以进行时间的加减操作
pd.Timedelta('1 D')
pd.Timestamp('2019-01-01 00:00:00')
2.新建一个空的Dataframe
new = pd.DataFrame(columns=['valid_time_gmt','origin_time','temp','wc','rh','vis','wspd','precip_hrly','wx_phrase'])
3. 从字典创建DataFrame
dict = {'user':['zhangsan','lisi','wangwu'],'age':['20','24','45'], 'gender':['male', 'male', 'male']}
data = pd.DataFrame(dict)
# 或创建一个随机的df
# (下面这个是抄的别人的:https://www.cnblogs.com/lhjc/p/12807630.html)
df = pd.DataFrame({
'A': pd.date_range(start='2016-01-01',periods=N,freq='D'),#freq设置步长,默认D表示日
'x': np.linspace(0,stop=N-1,num=N),#数列,起始点,结尾点,元素个数
'y': np.random.rand(N),
'C': np.random.choice(['Low','Medium','High'],N).tolist(),
'D': np.random.normal(100, 10, size=(N)).tolist()
})
4. 调整列顺序
直接输入新的顺序即可
data = data[['age', 'gender', 'name']]
5. 调整索引从1开始
data.index = range(1, len(data)+1)
6.dataframe中增加 行/列
# 增加行可以先新建一个df,再append进去
new=pd.DataFrame({'valid_time_gmt':new_time,
'temp':8,
'wc':6,
'rh':93,
'vis':8,
'wspd':11,
'precip_total':np.NaN,
'precip_hrly':4.1,
'wx_phrase':'Heavy Rain'}, index=[len(data)])
data = data.append(new)
# 增加列
data['count'] = 1
7.从字典新建DataFrame
8.向DataFrame中添加字典
9.dataframe删除 行/列
data = data.drop(0) # 删除行,括号中为行索引
data = data.drop('precip_total', axis=1) # 删除列,输入列名
10.筛选出该列 不为空的值
data[data['precip_total'].notnull()]
所以如果要找出为空的就应该是:data[data['precip_total'].isnull()]
11.找出有空值的列
data.isnull().any()
12.找出有空值的行
data[data.isnull().T.any()]
13. data.iloc[1] 与 data.loc[1]
这两个都是按行取值,但iloc里接收的是行号(即从第0行数起第几行)、loc是取的索引。如果数据的索引是有序且连序的,则它俩取出的值是一样的
如果要按行取第一行,第三行,第五行,可以这样:
data.iloc[[1, 3, 5]]
如果要连续取第一到第五行可以这样:
data.iloc[1:5]
14.修改列名
- 可以直接赋值新列名
data.columns = ['time', 'demand', longitude', 'latitude']
- df.rename
data.rename(columns={'Longitude':'longitude', 'Latitude':'latitude'}, inplace=True)
15.判断并删除重复行
data.duplicated()
可以用来判断重复行,两行除索引外完全重复(即对所有列判断)
删除重复行:data = data.drop_duplicates()
如果只想对某一列进行判断:
data.duplicated(['Feeder'])
data.drop_duplicates(['Feeder'])
判断重复的行
dup_row = all_three.duplicated(subset=["地市", "名称", "告警源", "最近发生时间"])
#all_three.insert(0, "duplicated", dup_row)
all_three["duplicated"] = dup_row
all_three[all_three["duplicated"]==True]
16.增加显示的行列数(不显示省略号)
pd.set_option('max_columns',500)
pd.set_option('max_row',500)
pd.set_option('max_colwidth',100)
17.对空值列填充
此处以填充浮点0为例
data['precip_hrly'] = data['precip_hrly'].fillna(0.0)
如果要填充空值,可以用pd.NA
代替np.nan
,它代表空整数、空布尔、空字符
如果是现有的空值,可以用<NA>
做为字符串来找到它
18.更改pandas中某个值
可以用这样,但这不是推荐的做法,因为会出现警告
new.loc[8825]['wx_phrase'] = 'T-Storm'
更推荐的做法是这样:
new.loc[8825,'wx_phrase'] = 'T-Storm'
19.批量替换某列中某个类型的值
可以将要替换的某个类型与替换后的类型放到字典里去,再这样对应替换一下
replace = dict{'Drizzle and Fog':'Fog'}
new['wx_phrase'] = new.wx_phrase.replace(replace)
20.DataFrame抽样
DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
-
n是要抽取的行数
-
frac是抽取的比例(0-1之间,frac=0.8,就是抽取其中80%)
-
replace:是否为有放回抽样,replace=True时为有放回抽样。replace=False(默认为False)是无放回的采样,当采样数n大于样本数且没有设置replace=True时,会出现异常
-
weights:指定样本抽中的概率,默认等概论抽样;
-
random_state:指定抽样的随机种子,可以使得每次抽样的种子一样,每次抽样结果一样
21. DataFrame的遍历
假设我有这样一个df,其中前两列均为索引列(索引的值是粗体的,默认情况没有索引列),可以用下面两种方式遍历
- df.itertuples()
i = 0
for index,row in group.itertuples():
print(index, row)
i += 1
if i>2:break
输出:
(0, 0) 5452
(0, 1) 42
(0, 2) 1183
- df.iterrows()
for index, row in group.iterrows():
print("index : ", index)
print("+"*20)
print("row : ", row)
print("-"*20)
print(row["count"])
break
输出:
index : (0, 0)
++++++++++++++++++++
row : count 5452
Name: (0, 0), dtype: int64
--------------------
5452
对于没有索引列的情况:df如果长如下这样
1. data.itertuples()
for row in data.itertuples():
print(row) # 因为没有索引列,所以遍历的时候只能用一个row来接收
print("-"*20)
print(row[0], row[1], row[2]) # 因为我的数据有三列
break
输出:
Pandas(Index=0, PULocationID=33, DOLocationID=55, count=1)
--------------------
0 33 55
- data.iterrows()
for index, row in data.iterrows():
print("index: ", index) # 可以看到这个是有索引的
print(row)
print("-"*20)
print(row[0], row[1], row["count"])
break
输出:
index: 0
PULocationID 33
DOLocationID 55
count 1
Name: 0, dtype: int64
--------------------
33 55 1
遍历方法的速度对比:根据以下引用文章结论,itertuples比iterrows快不少
22. 找出每列的不同数据类型数
经常在我们读取到一个文件时,它的列类型是object,这样的列中可能混有不同的类型,使后面的操作报错
我们可以这样,查看该列含有类型数量
然后,在后面就可以方便排查我们后面出现的报错,如:TypeError: '<' not supported between instances of 'float' and 'Timestamp'
这就是一列中即有时间戳类型,又有浮点类型,使之不支持排序、加减、比较等操作
23. 列类型转换
如果该列有空值的话可能会转换失败
如IntCastingNaNError: Cannot convert non-finite values (NA or inf) to integer
转换成整型的可以这样data["RNC编号"].astype("Int64")
,代替原来的astype(int)
24. 由一列的值改变另一列的值
如,我想将ratio
列中不为零的行的angle
字段对应值置为1,就可以这样
branch.loc[branch.ratio !=0, "angle"] = 1
当然条件那里可以有多个条件一起筛选
25. 行间求差
求不同行之间的差值,例如想求df中某一列是否为等差数列,就可以看每两行的差值是否相等
如有这样一个df,我想求第2列是否为等差数列
有两种方法:
- 做出一个新列,俩这两列相减
samp["diff"] = samp[2] - samp[2].shift(1)
samp
- shift(1)表示将这一列整体向下移动一行(移动一个索引,即原来行索引为0的,现在变成了1,1的变到了行索引为2的位置,索引0的位置补Null),如果是-2则表示往上移两行
samp["diff"] = samp.diff()[2].fillna(0)
samp
- diff()会自动求每两行内各字段的差值,单独调用diff(),会得到下面的结果,如果我们只想求第2列的差,就只用取这个结果的第2列
26. 判断某列数据在不在列表中
比如下面这个例子,我想筛选出PULocationID这一列中的值在exc列表中的数据,有下面两种方法:
data[data.PULocationID.isin(exc)]
(推荐使用)data.PULocationID[data.apply(lambda x:x.PULocationID in exc, axis=1)]
但是经过测试发现这两种方法速度差距很大,如我的data有7百多万行,分别执行两个方法的时间为:1. 692ms, 2. 9min 53s,所以推荐使用第一个,因为apply也是要遍历每一行来判断的,速度比较慢
如果是判断不在的话,目前就只知道用apply,然后上面的in 改成 not in。但是考虑到代价问题,建议将exc这个列表取反,然后依然用isin()这样会快些。
27. 判断一天是周几
现在有如下DataFrame,要找出时间pickup_datetime列对应的日期是周几,可以这样
tmp["week_of_day"] = tmp["pickup_datetime"].dt.dayofweek
tmp["week_day_name"] = tmp["pickup_datetime"].dt.day_name()
也可以通过这种方式判断当天是否是周末
28.对列做One-hot编码
pd.get_dummies(df, columns=)
可以将DataFrame中的一列或多列制作成One-hot编码,例如有如下df(这个只是抽样出来的几行),我只想将其它的diw与dim两列做成one-hot形式。
结果出下图,可以看到diw列只有四个不同值,所以生成的向量为四维,最后两行都是7,所以生成的向量是一致的。而dim有5个不同值,所以生成了五个不同向量。
删除变量 回收内存
在循环处理多个大文件的时候比较适用,但似乎用处不是很明显
import gc
del data # 删除data变量
gc.collect() # 回收内存
持续更新中…
下次更新mask函数的用法