Pandas是一个广泛用于处理结构化数据的Python包。网络上已经有很多很好的教程,但在这里我还是想介绍一些读者可能以前不知道的很酷的技巧,我相信它们很有用。
read_csv
每个人都知道这个命令。但是当你想要读取的数据很大时,那么在加载整个表之前,可以尝试添加这个参数:nrows = 5来读取表的一小部分。这样你就可以避免选择了错误分隔符这类问题(分隔符并非总是逗号形式)。
(或者,您可以在linux中使用’head’命令检查任何文本文件中的前5行(例如):head -c 5 data.txt)
然后,您可以通过使用df.columns.tolist()
提取所有列来提取列列表,然后添加usecols = ['c1','c2',...]
参数来加载所需的列。此外,如果您知道几个特定列的数据类型,还可以通过添加参数dtype = {'c1':str,'c2':int,...}
,来加快加载速度。此参数的另一个优点是,如果您有一个包含字符串和数字的列,那么将其类型声明为字符串是一个好习惯,这样在尝试使用此列作为键合并表时就不会出错。
select_dtypes
如果数据预处理必须在Python中完成,那么这个命令可以节省你一些时间。读入表后,每列的默认数据类型可以是bool
,int64
,float64
,object
,category
,timedelta64
或者datetime64
。您可以通过下面的命令查看数据分布情况来了解dataframe中的数据类型1
df.dtypes.value_counts()
然后执行1
df.select_dtypes(include=[‘float64’, ‘int64’])
来选择数值类型的dataframe。
copy
如果您还没有听说过,那么这是一个重要的命令。执行以下语句:1
2
3
4
5import pandas as pd
df1 = pd.DataFrame({ 'a':[0,0,0], 'b': [1,1,1]})
df2 = df1
df2['a'] = df2['a'] + 1
df1.head()
你会发现df1已经改变了。这是因为df2 = df1没有复制df1并将其分配给df2,而是设置了指向df1的指针。因此,df2的任何变化都会导致df1发生变化。要解决这个问题,你可以采取下面的方法1
df2 = df1.copy()
或者1
2from copy import deepcopy
df2 = deepcopy(df1)
map
这是一个进行数据转换的很酷的命令。首先定义一个字典,其中’keys’是旧值,’values’是新值。1
2level_map = {1:'high',2:'medium',3:'low'}
df ['c_level'] = df ['c'].map(level_map)
比如:True,False转换为1,0编码(用于建模); 定义分段水平; 用户自定义的字典编码。
apply
如果我们想创建一个包含其他几列作为输入的新列,那么apply函数将非常有用。1
2
3
4
5
6
7
8def rule(x, y):
if x == 'high' and y > 10:
return 1
else:
return 0
df = pd.DataFrame({ 'c1':[ 'high' ,'high', 'low', 'low'], 'c2': [0, 23, 17, 4]})
df['new'] = df.apply(lambda x: rule(x['c1'], x['c2']), axis = 1)
df.show()
在上面的代码中,我们定义了一个带有两个输入变量的函数,并使用apply函数将它应用于列'c1'
和'c2'
。
但apply
的问题是它有时太慢了。比如你想计算两列'c1'
和'c2'
的最大值,你当然可以这样做1
df['maximum'] = df.apply(lambda x: max(x['c1'], x['c2']), axis = 1)
但你会发现它比这个命令慢得多:1
df['maximum'] = df[['c1','c2']].max(axis =1)
注意:如果您可以使用其他内置函数完成相同的工作(它们通常更快),请不要使用apply
。例如,如果要将列'c'
舍入为整数,请执行round(df ['c'],0)
而不是使用apply
函数。
value_counts
这是检查值数值分布的命令。如果您想检查c
列中每个值的可能值和频率,您可以执行此操作1
df['c'].value_counts()
这个命令还有一些有用的技巧和参数:
A.normalize = True
:如果你要检查是频率,而不是计数。
B.dropna = False
:如果你还想在统计数据中包含缺失值。
C.sort = False
:显示按值而不是计数排序的统计数据。
D.df['c'].value_counts().reset_index()
如果你想将统计表转换成pandas dataframe并进行操作。
缺失值
构建模型时,您可能希望排除具有太多缺失值的行/具有所有缺失值的行。您可以使用.isnull()
和.sum()
来计算指定列中缺失值的数量。
1 | import pandas as pd |
选择具有特定ID的行
在SQL中,我们可以使用SELECT * FROM ... WHERE ID('A001','C022',...)
来获取具有特定ID的记录。如果你想用pandas做同样的事情,你可以这样做1
2df_filter = df['ID'].isin(['A001','C022',...])
df[df_filter]
百分位组
您有一个数值列,并希望将该列中的值进行分组,例如组1中的前5%,组2中的5-20%,组3中的20%-50%,组4中的50%。当然,你可以用pandas.cut
来做,但我想在这里提供另外一种选择:1
2
3
4
5
6import numpy as np
cut_points = [np.percentile(df['c'], i) for i in [50, 80, 95]]
df['group'] = 1
for i in range(3):
df['group'] = df['group'] + (df['c'] < cut_points[i])
# or <= cut_points[i]
能够快速运行(没有使用apply
方法)。
to_csv
这也是每个人都会使用的命令。我想在这里指出两个技巧。第一个是1
print(df[:5].to_csv())
您可以使用此命令打印出需要写入文件的前五行。
另一个技巧用来处理混合在一起的整数和缺失值。如果列包含缺失值和整数,则数据类型则是float而不是int。导出表时,可以添加float_format='%.0f'
将所有浮点数舍入为整数。如果您只想要所有列的整数输出,请使用此技巧——您将摆脱令人烦恼的小数部分。