第六章缺失值处理pandas
目录标题
第六章缺失数据
缺失观测及其类型
检测缺失值isna和notna返回布尔值
isna()是查找是缺失值的返回True,反之False
df[‘Physics’].isna().head()
0 False
1 False
2 False
3 True
4 False
Name: Physics, dtype: bool
notna()查找不是缺失值的,返回值跟上面相反
df[‘Physics’].notna().head()
0 True
1 True
2 True
3 False
4 True
Name: Physics, dtype: bool
可以添加sum()来统计每行每列的缺失值个数
df.isna().sum()
School 0
Class 4
ID 6
Gender 7
Address 0
Height 0
Weight 13
Math 5
Physics 4
dtype: int64
也可以通过info来查看缺信息
df.info()
<class ‘pandas.core.frame.DataFrame’>
RangeIndex: 35 entries, 0 to 34
Data columns (total 9 columns):
#Column Non-Null Count Dtype
0 School 35 non-null object
1 Class 31 non-null object
2 ID 29 non-null float64
3 Gender 28 non-null object
4 Address 35 non-null object
5 Height 35 non-null int64
6 Weight 22 non-null float64
7 Math 30 non-null float64
8 Physics 31 non-null object
dtypes: float64(3), int64(1), object(5)
memory usage: 2.6+ KB
np.nan的几个知识点
1.np.nan它不等与任何东西,甚至不等于自己
2.用equals函数比较时,自动略过两侧全是np.nan的单元格,因此结果不会影响
3.它在numpy中的类型为浮点,由此导致数据集读入时,即使原来是整数的列,只要有缺失值就会变为浮点型
4.对于布尔类型的列表,如果是np.nan填充,那么它的值会自动变为True而不是False
pd.Series([1,np.nan,3],dtype=‘bool’)
0 True
1 True
2 True
dtype: bool
5.但当修改一个布尔列表时,会改变列表类型,而不是赋值为True
s = pd.Series([True,False],dtype=‘bool’)
s[1]=np.nan
s
0 1.0
1 NaN
dtype: float64
可以认为None跟这个np.nan相反,NaT可以看作是时序版的np.nan
Nullable类型与NA符号
这是Pandas在1.0新版本中引入的重大改变,其目的就是为了(在若干版本后)解决之前出现的混乱局面,统一缺失值处理方法
“The goal of pd.NA is provide a “missing” indicator that can be used consistently across data types (instead of np.nan, None or pd.NaT depending on the data type).”——User Guide for Pandas v-1.0
官方鼓励用户使用新的数据类型和缺失类型pd.NA
Nullable整形
对于该种类型而言,它与原来标记int上的符号区别在于首字母大写:‘Int’
它的好处就在于,其中前面提到的三种缺失值都会被替换为统一的NA符号,且不改变数据类型
Nullable布尔
对于该种类型而言,作用与上面的Nullable整形类似,记号为boolean
string类型
类型是1.0的一大创新,目的之一就是为了区分开原本含糊不清的object类型,它本质上也属于Nullable类型,因为并不会因为含有缺失而改变类型
此外,和object类型的一点重要区别就在于,在调用字符方法后,string类型返回的是Nullable类型,object则会根据缺失类型和数据类型而改
NA的特性
逻辑运算
只需看该逻辑运算的结果是否依赖pd.NA的取值,如果依赖,则结果还是NA,如果不依赖,则直接计算结果
算术运算和比较运算
这里只需记住除了下面两类情况,其他结果都是NA即可
pd.NA ** 0
1
1 ** pd.NA
1
convert_dtypes方法
这个函数的功能往往就是在读取数据时,就把数据列转为Nullable类型,是1.0的新函数
缺失数据的运算与分组
加号与乘号规则
使用加法时,缺失值为0
使用乘法时,缺失值为1
使用累计函数时,缺失值自动略过
groupby方法中的缺失值
自动忽略为缺失值的组
填充与剔除
fillna方法
值填充与前后向填充(分别与ffill方法和bfill方法等价)
df[‘Physics’].fillna(method=‘ffill’).head()
0 A+
1 B+
2 B+
3 B+
4 A-
Name: Physics, dtype: object
df[‘Physics’].fillna(method=‘backfill’).head()
0 A+
1 B+
2 B+
3 A-
4 A-
Name: Physics, dtype: object
填充中的对齐特性
df_f.fillna(df_f.mean())
dropna方法
axis参数
df_d.dropna(axis=0)
对行无缺失值的
df_d.dropna(axis=1)
对列无缺失值的
how参数(可以选all或者any,表示全为缺失去除和存在缺失去除)
df_d.dropna(axis=1,how=‘all’)
删除所有都是缺失值的列
subset参数(即在某一组列范围中搜索缺失值)
df_d.dropna(axis=0,subset=[‘B’,‘C’])
删除B,C含有缺失值的行
插值(interpolation)
线性插值
索引无关的线性插值
默认状态下,interpolate会对缺失的值进行线性插值
s = pd.Series([1,10,15,-5,-2,np.nan,np.nan,28])
0 1.0
1 10.0
2 15.0
3 -5.0
4 -2.0
5 NaN
6 NaN
7 28.0
dtype: float64
s.interpolate()
0 1.0
1 10.0
2 15.0
3 -5.0
4 -2.0
5 8.0
6 18.0
7 28.0
dtype: float64
s.interpolate().plot()
此时的插值与索引无关
与索引有关的插值
method中的index和time选项可以使插值线性地依赖索引,即插值为索引的线性函数
s.interpolate(method=‘index’).plot()
如果索引是时间,那么可以按照时间长短插值
s_t.interpolate().plot()
s_t.interpolate(method=‘time’).plot()
高级插值方法
此处的高级指的是与线性插值相比较,例如样条插值、多项式插值、阿基玛插值等(需要安装Scipy)
关于这部分仅给出一个官方的例子,因为插值方法是数值分析的内容,而不是Pandas中的基本知识:
ser = pd.Series(np.arange(1, 10.1, .25) ** 2 + np.random.randn(37))
missing = np.array([4, 13, 14, 15, 16, 17, 18, 20, 29])
ser[missing] = np.nan
methods = [‘linear’, ‘quadratic’, ‘cubic’]
df = pd.DataFrame({m: ser.interpolate(method=m) for m in methods})
df.plot()
interpolate中的限制参数
limit表示最多插入多少个
s = pd.Series([1,np.nan,np.nan,np.nan,5])
s.interpolate(limit=2)
0 1.0
1 2.0
2 3.0
3 NaN
4 5.0
dtype: float64
limit_direction表示插值方向,可选forward,backward,both,默认前向
limit_area表示插值区域,可选inside,outside,默认None
练习
【练习一】现有一份虚拟数据集,列类型分别为string/浮点/整型,请解决如下问题:
(a)请以列类型读入数据,并选出C为缺失值的行。
a = pd.read_csv(‘data/Missing_data_one.csv’)
b = a.isnull()
c = a[b]
c
(b)现需要将A中的部分单元转为缺失值,单元格中的最小转换概率为25%,且概率大小与所在行B列单元的值成正比。
total_b = a[‘B’].sum()
min_b = a[‘B’].min()
a[‘A’] = pd.Series(list(zip(a[‘A’].values,a[‘B’].values))).apply(lambda x:x[0] if np.random.rand()>0.25*x[1]/min_b else np.nan)
a