在做数据清洗等工作时,必不可少的环节就是缺失值处理。在采用pandas读取或处理数据时,dataframe的缺失值默认是用nan填充的。但大多数情况下,我们需要的是None或者Null值而不是nan.所以,如何替换dataframe中的nan呢?
替换nan的方法有很多,本文总结了三个方法。dataframe.fillna()方法,dataframe.applymap()以及dataframe.where()方法。本文通过测试数据对每个方法进行分析。最终选择使用哪个方法可结合本文的分析,根据真实场景进行取舍。
1.准备测试数据
types = {'name': str, 'cost': float, 'age': float, 'phone': str}
# 注意age不能指定为int类型,
# 指定类型读取数据
data = pd.read_excel('../../test.xlsx', sheet_name='Sheet1', header=0, dtype=types)
#查看数据
print(data)
# 查看每列的数据类型
print(data.dtypes)
注意:age列中含有缺失值,所以不能指定为int型,否则会报错:ValueError: Unable to convert column age to type
输出结果:
name cost age phone
0 小青 NaN 25.0 12341234123
1 小红 1.628771e+06 23.0 12341234124
2 小明 8.438553e+05 26.0 12341234125
3 小李 1.699444e+06 25.0 12341234126
4 小王 2.635745e+06 NaN 12341234127
5 小张 1.168142e+06 25.0 nan
6 小刘 1.607670e+06 28.0 12341234129
7 nan 1.234523e+04 27.0 nan
name object
cost float64
age float64
phone object
dtype: object
Process finished with exit code 0
2.dataframe.fillna();该方法使用指定的方法填充NA / NaN值
values = {'name': '', 'cost': 0, 'age': -1, 'phone': ''}
data.fillna(value=values,inplace=True)
print(data)
输出结果:
name cost age phone
0 小青 0.000000e+00 25.0 12341234123
1 小红 1.628771e+06 23.0 12341234124
2 小明 8.438553e+05 26.0 12341234125
3 小李 1.699444e+06 25.0 12341234126
4 小王 2.635745e+06 -1.0 12341234127
5 小张 1.168142e+06 25.0 nan
6 小刘 1.607670e+06 28.0 12341234129
7 nan 1.234523e+04 27.0 nan
Process finished with exit code 0
从上面的输出结果可以看出:fillna()方法必须要指定一个填充且不为None的值,且object类型的填充并未生效
3.dataframe.applymap()自定义处理方法
data = data.applymap(lambda x: x if str(x) != 'nan' else None)
# 查看数据
print(data)
输出结果:
name cost age phone
0 小青 NaN 25.0 12341234123
1 小红 1.628771e+06 23.0 12341234124
2 小明 8.438553e+05 26.0 12341234125
3 小李 1.699444e+06 25.0 12341234126
4 小王 2.635745e+06 NaN 12341234127
5 小张 1.168142e+06 25.0 None
6 小刘 1.607670e+06 28.0 12341234129
7 None 1.234523e+04 27.0 None
Process finished with exit code 0
由上面的输出结果可以看出:该方法只对字符串类型的数据生效,数值类型的数据又不能起作用了
4.dataframe.where()筛选需要的数据,如果符合要求就返回原始值,如果不符合要求就用参数other的值填充,other的默认值为numpy.nan
4.1不指定数据类型
data = pd.read_excel('../../test.xlsx', sheet_name='Sheet1', header=0)
data = data.where((data.notna()),None)
# 查看数据
print(data)
输出结果:
name cost age phone
0 小青 None 25 1.23412e+10
1 小红 1.62877e+06 23 1.23412e+10
2 小明 843855 26 1.23412e+10
3 小李 1.69944e+06 25 1.23412e+10
4 小王 2.63574e+06 None 1.23412e+10
5 小张 1.16814e+06 25 None
6 小刘 1.60767e+06 28 1.23412e+10
7 None 12345.2 27 None
Process finished with exit code 0
注意:上面代码中使用where方法时,读取测试数据并没有指定name为str类型,如果指定为str类型,则pandas读取该列时缺失值采用字符串'nan'进行填充,data.notna()返回的是True,如果不指定name列的类型,则该列的缺失值使用float类型的numpy.nan填充,data.notna()返回的是False。
4.2 指定数据类型,可自定的where方法的cond参数
types = {'name': str, 'cost': float, 'age': float, 'phone': str}
# 指定类型读取数据
data = pd.read_excel('../../test.xlsx', sheet_name='Sheet1', header=0, dtype=types)
data = data.where((data.applymap(lambda x: True if str(x) != 'nan' else False)), None)
# 查看数据
print(data)
输出结果:
name cost age phone
0 小青 None 25 12341234123
1 小红 1.62877e+06 23 12341234124
2 小明 843855 26 12341234125
3 小李 1.69944e+06 25 12341234126
4 小王 2.63574e+06 None 12341234127
5 小张 1.16814e+06 25 None
6 小刘 1.60767e+06 28 12341234129
7 None 12345.2 27 None