Pandas缺失值填充5大技巧
本文记录Pandas中缺失值填充的5大技巧:
- 填充具体数值,通常是0
- 填充某个统计值,比如均值、中位数、众数等
- 填充前后项的值
- 基于SimpleImputer类的填充
- 基于KNN算法的填充
数据
1 | import pandas as pd |
1 | df = pd.DataFrame({ |
A | B | C | |
---|---|---|---|
0 | 1 | 5 | 9 |
1 | 2 | 6 | 10 |
2 | 3 | 7 | 11 |
3 | 4 | 8 | 12 |
4 | 5 | 9 | 13 |
5 | 6 | 10 | 14 |
6 | 7 | 11 | 15 |
7 | 8 | 12 | 16 |
设置空值
1 | df.iloc[0,2] = np.nan |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | NaN |
1 | 2.0 | 6.0 | 10.0 |
2 | NaN | 7.0 | 11.0 |
3 | 4.0 | NaN | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | NaN | 15.0 |
7 | 8.0 | 12.0 | NaN |
统计空值个数
1 | # 统计每列下空值的个数 |
A 1
B 2
C 2
dtype: int64
1 | df[(df.isnull()).any(axis=1)] |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | NaN |
2 | NaN | 7.0 | 11.0 |
3 | 4.0 | NaN | 12.0 |
6 | 7.0 | NaN | 15.0 |
7 | 8.0 | 12.0 | NaN |
方法1:填充具体数值
1 | df.fillna(0) # 一般是填充0 |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | 0.0 |
1 | 2.0 | 6.0 | 10.0 |
2 | 0.0 | 7.0 | 11.0 |
3 | 4.0 | 0.0 | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | 0.0 | 15.0 |
7 | 8.0 | 12.0 | 0.0 |
1 | df.fillna(33) # 填充其他数值 |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | 33.0 |
1 | 2.0 | 6.0 | 10.0 |
2 | 33.0 | 7.0 | 11.0 |
3 | 4.0 | 33.0 | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | 33.0 | 15.0 |
7 | 8.0 | 12.0 | 33.0 |
方法2:填充统计值
1 | df1 = df.copy() # 方便演示,生成副本 |
1 | df1["A"].mean() |
4.714285714285714
1 | (1+2+4+5+6+7+8) / 7 |
4.714285714285714
1 | # 每列的空值填充各自的均值 |
A | B | C | |
---|---|---|---|
0 | 1.000000 | 5.000000 | 12.5 |
1 | 2.000000 | 6.000000 | 10.0 |
2 | 4.714286 | 7.000000 | 11.0 |
3 | 4.000000 | 8.166667 | 12.0 |
4 | 5.000000 | 9.000000 | 13.0 |
5 | 6.000000 | 10.000000 | 14.0 |
6 | 7.000000 | 8.166667 | 15.0 |
7 | 8.000000 | 12.000000 | 12.5 |
方法3:前后项填充
1 | df2 = df.copy() # 生成副本 |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | NaN |
1 | 2.0 | 6.0 | 10.0 |
2 | NaN | 7.0 | 11.0 |
3 | 4.0 | NaN | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | NaN | 15.0 |
7 | 8.0 | 12.0 | NaN |
1 | # 1、前项填充 f-forward |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | NaN |
1 | 2.0 | 6.0 | 10.0 |
2 | 2.0 | 7.0 | 11.0 |
3 | 4.0 | 7.0 | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | 10.0 | 15.0 |
7 | 8.0 | 12.0 | 15.0 |
1 | # 2、后项填充 b-back |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | 10.0 |
1 | 2.0 | 6.0 | 10.0 |
2 | 2.0 | 7.0 | 11.0 |
3 | 4.0 | 7.0 | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | 10.0 | 15.0 |
7 | 8.0 | 12.0 | 15.0 |
方法4:SimpleImputer类填充(单变量)
1 | sklearn.impute.SimpleImputer (missing_values=nan, |
- missing_values:int, float, str, (默认)np.nan或是None, 指明缺失值长什么样子
- strategy:空值填充的方法
- mean:均值,默认
- median:中位数
- most_frequent:众数
- constant:自定义的值,必须通过fill_value来定义。
- fill_value:str或数值,默认为Zone。当strategy == “constant"时,fill_value被用来替换所有出现的缺失值(missing_values)。fill_value为Zone,当处理的是数值数据时,缺失值(missing_values)会替换为0,对于字符串或对象数据类型则替换为"missing_value” 这一字符串。
- verbose:int,(默认)0,控制imputer的冗长。
- copy:boolean,(默认)True,表示对数据的副本进行处理(原数据不改变),False对数据直接原地修改。
- add_indicator:boolean,(默认)False,True则会在数据后面加入n列由0和1构成的同样大小的数据,0表示所在位置非缺失值,1表示所在位置为缺失值。
1 | from sklearn.impute import SimpleImputer |
1 | # 案例1 |
array([[ 1. , 5. , 12.5 ],
[ 2. , 6. , 10. ],
[ 4.71428571, 7. , 11. ],
[ 4. , 8.16666667, 12. ],
[ 5. , 9. , 13. ],
[ 6. , 10. , 14. ],
[ 7. , 8.16666667, 15. ],
[ 8. , 12. , 12.5 ]])
1 | df3 # 不是原地修改,df3不会改变 |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | NaN |
1 | 2.0 | 6.0 | 10.0 |
2 | NaN | 7.0 | 11.0 |
3 | 4.0 | NaN | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | NaN | 15.0 |
7 | 8.0 | 12.0 | NaN |
1 | # 案例2 |
array([[ 1. , 5. , 12.5],
[ 2. , 6. , 10. ],
[ 5. , 7. , 11. ],
[ 4. , 8. , 12. ],
[ 5. , 9. , 13. ],
[ 6. , 10. , 14. ],
[ 7. , 8. , 15. ],
[ 8. , 12. , 12.5]])
1 | df3 # df3已经改变 |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | 12.5 |
1 | 2.0 | 6.0 | 10.0 |
2 | 5.0 | 7.0 | 11.0 |
3 | 4.0 | 8.0 | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | 8.0 | 15.0 |
7 | 8.0 | 12.0 | 12.5 |
1 | # 案例3:不同的列采取不同策略填充 |
1 | df4["A"] = df_mean.fit_transform(df4["A"].values.reshape(-1,1)) # 均值 |
A | B | C | |
---|---|---|---|
0 | 1.000000 | 5.0 | 10.0 |
1 | 2.000000 | 6.0 | 10.0 |
2 | 4.714286 | 7.0 | 11.0 |
3 | 4.000000 | 8.0 | 12.0 |
4 | 5.000000 | 9.0 | 13.0 |
5 | 6.000000 | 10.0 | 14.0 |
6 | 7.000000 | 8.0 | 15.0 |
7 | 8.000000 | 12.0 | 10.0 |
方法5:基于KNN填充
1 | from sklearn.impute import KNNImputer |
1 | df5 = df.copy() |
A | B | C | |
---|---|---|---|
0 | 1.0 | 5.0 | NaN |
1 | 2.0 | 6.0 | 10.0 |
2 | NaN | 7.0 | 11.0 |
3 | 4.0 | NaN | 12.0 |
4 | 5.0 | 9.0 | 13.0 |
5 | 6.0 | 10.0 | 14.0 |
6 | 7.0 | NaN | 15.0 |
7 | 8.0 | 12.0 | NaN |
1 | # 最近的3个邻居,使用的是3者的均值 |
array([[ 1. , 5. , 11. ],
[ 2. , 6. , 10. ],
[ 2.33333333, 7. , 11. ],
[ 4. , 7.33333333, 12. ],
[ 5. , 9. , 13. ],
[ 6. , 10. , 14. ],
[ 7. , 10.33333333, 15. ],
[ 8. , 12. , 14. ]])
填充值如何计算得来:
1 | print((1 + 2 + 4) / 3) |
2.3333333333333335
7.333333333333333
10.333333333333334
11.0
14.0