如何替换dataframe中的nan?

在做数据清洗等工作时,必不可少的环节就是缺失值处理。在采用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

 

你可能感兴趣的:(python,nan,dataframe,numpy.nan)