pandas

如何处理缺失数据

在练习中经常遇到pandas使用浮点值NaN来表示数组中的缺失数据。那我们该如何处理这些缺失数据?

In [228]: string_data = Series(['aardvark', 'artichoke', np.nan, 'avocado'])

In [229]: string_data
Out[229]:
0     aardvark
1    artichoke
2          NaN
3      avocado
dtype: object

In [230]: string_data.isnull()
Out[230]:
0    False
1    False
2     True
3    False
dtype: bool

通过isnull函数我们得知了Series对象中存在一个缺失数据。

In [231]: string_data.dropna()   #通过dropna函数直接清除缺失数据,并且不会影响后续数据的索引值
Out[231]:
0     aardvark
1    artichoke
3      avocado
dtype: object

常用的处理缺失数据的方法:
dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值的容忍度
fillna 用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull 返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值/NA,该对象的类型与源类型一样
notnull isnull的否定式

dropna函数的详细用法

使用dropna函数处理DataFrame对象

In [232]: data = DataFrame([[1, 6.5, 3], [1, np.nan, np.nan],[np.nan, np.nan, np.nan],[np.nan, 6.5, 3]])

In [233]: cleaned = data.dropna()

In [234]: data
Out[234]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

In [235]: cleaned
Out[235]:
     0    1    2
0  1.0  6.5  3.0

可以看到,dropna函数很暴力的把带有NaN的行都给清除掉了。有没有保留非缺失数据的做法:

In [236]: data.dropna(how='all')  #通过传入how='all',只清除全部都是NaN的行
Out[236]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
3  NaN  6.5  3.0

要清除某列中的缺失数据:

In [237]: data[4] = np.nan

In [238]: data
Out[238]:
     0    1    2   4
0  1.0  6.5  3.0 NaN
1  1.0  NaN  NaN NaN
2  NaN  NaN  NaN NaN
3  NaN  6.5  3.0 NaN

In [239]: data.dropna(axis=1, how='all')
Out[239]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

如果想在清除过程中保留整行中有一个空缺值的行:

In [248]: data.dropna(thresh=2)
Out[248]:
     0    1    2
0  1.0  6.5  3.0
3  NaN  6.5  3.0

填充缺失数据

如果不想清除这些缺失数据,想改为可用或者不影响计算的数据,我们可以用fillna函数

In [249]: data.fillna(0)
Out[249]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  0.0  0.0
2  0.0  0.0  0.0
3  0.0  6.5  3.0

我们把所有的空缺值都改为了0

也可以对不同列填充不同的值:

In [250]: data.fillna({0: 0.5, 1: 1.5})   #这里我们将第1列中的空缺值改为了0.5,将第二列的空缺值改为了1.5
Out[250]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  1.5  NaN
2  0.5  1.5  NaN
3  0.5  6.5  3.0

通过传入字典的形式可以对每一列进行操作。

fillna函数默认是不会修改源数据的,会返回一个填充好的新对象。当然我们可以通过inplace选项来达到直接修改源数据的目的。

In [259]: data.fillna(0)
Out[259]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  0.0  0.0
2  0.0  0.0  0.0
3  0.0  6.5  3.0

In [260]: data
Out[260]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

In [261]: data.fillna(0, inplace=True)

In [262]: data
Out[262]:
     0    1    2
0  1.0  6.5  3.0
1  1.0  0.0  0.0
2  0.0  0.0  0.0
3  0.0  6.5  3.0

常用的fillna函数的参数

value 用于填充缺失值的标量值或字典对象
method 插值方式。如果函数调用时未指定其他参数的话,默认为’ffill’
axis 待填充的轴,默认axis=0
inplace 修改调用者对象而不产生副本
limit 对填充设置可以连续填充的最大数量