3.5 处理缺失值
涉及的缺失值主要有三种形式: null NaN NA
选择处理缺失值的方法
- 用覆盖全局的掩码
- 用特定的标签值表示缺失值
Pandas的缺失值
采用标签值表示缺失值
None:Python对象类型的缺失值
是Python单体对象,在代码中表示缺失值,只能用于Object对象组成的数组中的对象,不能用作任何np或pd数组类型的缺失值。
import numpy as np
import pandas as pd
vals1 = np.array([1, None, 3, 4])
vals1 # 由于有None,数组对象类型为Python的Object类型
array([1, None, 3, 4], dtype=object)
# Python类型运算性能较低,而且包括None对象将导致数值运算错误
vals1.sum()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-3-57ce7f3f1935> in <module>() 1 # Python类型运算性能较低,而且包括None对象将导致数值运算错误 ----> 2 vals1.sum() c:\program files\python36-32\lib\site-packages\numpy\core\_methods.py in _sum(a, axis, dtype, out, keepdims) 30 31 def _sum(a, axis=None, dtype=None, out=None, keepdims=False): ---> 32 return umr_sum(a, axis, dtype, out, keepdims) 33 34 def _prod(a, axis=None, dtype=None, out=None, keepdims=False): TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
NaN:数值类型的缺失值
是在任何系统中都兼容的特殊浮点数:
vals2 = np.array([1, np.nan, 3, 4])
vals2 # 类型会为浮点数
array([ 1., nan, 3., 4.])
vals2.dtype
dtype('float64')
可将NaN看成“数据病毒”:任何数与其运算的结果均为NaN:
1 + np.nan
nan
0 * np.nan
nan
vals2.sum(), vals2.min(), vals2.max()
c:\program files\python36-32\lib\site-packages\numpy\core\_methods.py:29: RuntimeWarning: invalid value encountered in reduce return umr_minimum(a, axis, None, out, keepdims) c:\program files\python36-32\lib\site-packages\numpy\core\_methods.py:26: RuntimeWarning: invalid value encountered in reduce return umr_maximum(a, axis, None, out, keepdims)
(nan, nan, nan)
np提供了特殊的累计函数,可以忽略NaN的影响:
np.nansum(vals2), np.nanmin(vals2), np.nanmax(vals2)
(8.0, 1.0, 4.0)
Pandas 中 NaN 与 None 的差异
NaN与None在pd中可以等价交换,在适当时候会将两者进行替换:
pd.Series([1, np.nan, 2, None])
0 1.0 1 NaN 2 2.0 3 NaN dtype: float64
# pd会将没有标签值的数据类型自动转换为NaN,如整数的np.nan转换为浮点NaN
x = pd.Series(range(2), dtype=int)
x
0 0 1 1 dtype: int32
x[0] = None
x
0 NaN 1 1.0 dtype: float64
# object类型的None不会自动转化
x = pd.Series(range(2), dtype=object)
x
0 0 1 1 dtype: object
x[0] = None
x
0 None 1 1 dtype: object
处理缺失值
几个方法:
- isnull() 创建一个布尔类型的掩码标签缺失值
- notnull() 也创建布尔类型的掩码,结果与isnull操作相反
- dropna() 返回一个剔除缺失值的数据
- fillna() 返回一个填充了缺失值的数据副本
发现缺失值
方法isnull()和notnull()
data = pd.Series([1, np.nan, 'hello', None])
data.isnull()
0 False 1 True 2 False 3 True dtype: bool
data.notnull()
0 True 1 False 2 True 3 False dtype: bool
# 布尔类型掩码数组可以直接作为Series或DF的索引使用
data[data.notnull()]
0 1 2 hello dtype: object
剔除缺失值
data.dropna()
0 1 2 hello dtype: object
# 在DF上使用要设置一些参数
df = pd.DataFrame([[1, np.nan, 2],
[2, 3, 5],
[np.nan, 4, 6]])
df
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | NaN | 2 |
1 | 2.0 | 3.0 | 5 |
2 | NaN | 4.0 | 6 |
# DF只能剔除包含缺失值数据的整行或整列数据
# 默认剔除任何包含缺失值的整行
df.dropna()
0 | 1 | 2 | |
---|---|---|---|
1 | 2.0 | 3.0 | 5 |
# 剔除任何包含缺失值的整列,要用参数
df.dropna(axis='columns')
2 | |
---|---|
0 | 2 |
1 | 5 |
2 | 6 |
按照行或列中缺失值的数量来剔除缺失值,参数how和thresh
# 参数how默认为any,即任何缺失值存在则剔除
# 可将how设置为all,即行或列全为缺失值才剔除
df[3] = np.nan
df
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | NaN | 2 | NaN |
1 | 2.0 | 3.0 | 5 | NaN |
2 | NaN | 4.0 | 6 | NaN |
# 现在剔除掉全为缺失值的第三列
df.dropna(axis='columns', how='all')
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | NaN | 2 |
1 | 2.0 | 3.0 | 5 |
2 | NaN | 4.0 | 6 |
# thresh参数,设置行或列中、非缺失值(即有用数据)的最小数量
df.dropna(axis='rows', thresh=3)
0 | 1 | 2 | 3 | |
---|---|---|---|---|
1 | 2.0 | 3.0 | 5 | NaN |
填充缺失值
fillna方法可以返回填充了缺失值后的数组副本
data = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))
data
a 1.0 b NaN c 2.0 d NaN e 3.0 dtype: float64
# 用单独的值填充缺失值
data.fillna(0)
a 1.0 b 0.0 c 2.0 d 0.0 e 3.0 dtype: float64
# 可用缺失值前面的有效值从前往后填充(forwad-fill)
data.fillna(method='ffill')
a 1.0 b 1.0 c 2.0 d 2.0 e 3.0 dtype: float64
# 也可用缺失值后面的有效值从后往前填充(back-fill)
data.fillna(method='bfill')
a 1.0 b 2.0 c 2.0 d 3.0 e 3.0 dtype: float64
# df用法类似,但要设置坐标轴参数axis
df
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | NaN | 2 | NaN |
1 | 2.0 | 3.0 | 5 | NaN |
2 | NaN | 4.0 | 6 | NaN |
df.fillna(method='ffill', axis=1) # 按列填充,从第一列向后填充
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | 1.0 | 2.0 | 2.0 |
1 | 2.0 | 3.0 | 5.0 | 5.0 |
2 | NaN | 4.0 | 6.0 | 6.0 |