利用Python进行数据分析:缺失数据(基于DataFrame)

利用Python进行数据分析:缺失数据

最近在做一个数据分析类项目,涉及处理7万+名学生的全学程数据,数据以表格型结构化数据为主,涉及学生基本信息、成绩和课程信息、评奖评优、勤工助学及行为数据。借此机会,对项目中频繁使用的基于DataFrame 的Python 数据分析语句进行梳理。此篇主要针对缺失值的处理、过滤及填补方法。

#以下为涉及的Python包
import pandas as pd
import numpy as np

以下为pandas中一些关于缺失数据处理的函数。

方法说明
dropna根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值的容忍度
fillna用指定值或插值方法(如ffill或bfill填充缺失数据)
isnull返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值/NA,该对象的类型与源类型一样
notnullisnull的否定式
from numpy import nan as NA
data = pd.DataFrame([[1., 6.5, 3.,NA], [1., NA, NA,NA],
                     [NA, NA, NA,NA], [NA, 6.5, 3.,NA]])
data
0123
01.06.53.0NaN
11.0NaNNaNNaN
2NaNNaNNaNNaN
3NaN6.53.0NaN

滤除缺失数据

查找缺失数据:

data.isnull()
0123
0FalseFalseFalseTrue
1FalseTrueTrueTrue
2TrueTrueTrueTrue
3TrueFalseFalseTrue

可以逐列统计数据缺失情况:

for col in data.columns:
    print(f'{col}:{len(data[data[col].isnull()])/len(data)}')
0:0.5
1:0.5
2:0.5
3:1.0

滤除缺失数据,dropna默认丢弃任何含有缺失值的行:

data.dropna()
0123

传入how='all’将只丢弃全为NA的那些行:

data.dropna(how='all')
0123
01.06.53.0NaN
11.0NaNNaNNaN
3NaN6.53.0NaN

用这种方式丢弃列,只需传入axis=1即可:

data.dropna(how='all',axis=1)
012
01.06.53.0
11.0NaNNaN
2NaNNaNNaN
3NaN6.53.0

可以通过thresh参数控制保留至少几个非缺失值,这种在处理涉及时间序列类数据时会用到,用于留下部分观测数据以保留基本数据趋势。

#每行保留至少1个非缺失值
data.dropna(thresh=1)
0123
01.06.53.0NaN
11.0NaNNaNNaN
3NaN6.53.0NaN
#每行保留至少两个非缺失值
data.dropna(thresh=2)
0123
01.06.53.0NaN
3NaN6.53.0NaN

通过inplace=True直接改变原数据:

data
0123
01.06.53.0NaN
11.0NaNNaNNaN
2NaNNaNNaNNaN
3NaN6.53.0NaN
data.dropna(thresh=2,inplace = True)
data
0123
01.06.53.0NaN
3NaN6.53.0NaN

填充缺失数据

df = pd.DataFrame(np.random.randn(7, 3))
df.iloc[:4,1] = NA
df.iloc[:2,2] = NA
df
012
0-0.393415NaNNaN
1-0.174198NaNNaN
2-0.877172NaN-1.278562
3-0.499985NaN-0.096270
41.1955300.4287470.230859
50.3467500.020427-0.676320
61.701942-0.1002330.674782

统一将缺失值填充为0:

df.fillna(0)
012
0-0.3934150.0000000.000000
1-0.1741980.0000000.000000
2-0.8771720.000000-1.278562
3-0.4999850.000000-0.096270
41.1955300.4287470.230859
50.3467500.020427-0.676320
61.701942-0.1002330.674782

通过字典调用fillna,实现对不同列填充不同的值:

df.fillna({1:0.5,2:0})
012
0-0.3934150.5000000.000000
1-0.1741980.5000000.000000
2-0.8771720.500000-1.278562
3-0.4999850.500000-0.096270
41.1955300.4287470.230859
50.3467500.020427-0.676320
61.701942-0.1002330.674782

使用插值方法进行缺失值填充:

df.fillna(method='bfill')
012
0-0.3934150.428747-1.278562
1-0.1741980.428747-1.278562
2-0.8771720.428747-1.278562
3-0.4999850.428747-0.096270
41.1955300.4287470.230859
50.3467500.020427-0.676320
61.701942-0.1002330.674782
df.fillna(method='bfill', limit=2)
012
0-0.393415NaN-1.278562
1-0.174198NaN-1.278562
2-0.8771720.428747-1.278562
3-0.4999850.428747-0.096270
41.1955300.4287470.230859
50.3467500.020427-0.676320
61.701942-0.1002330.674782

只要有些创新,你就可以利用fillna实现许多别的功能。比如说,使用均值进行缺失值填充,也可以传入最小值、中位数:

#将缺失值填充为所在列均值
df.fillna(df.mean(axis=0))
012
0-0.3934150.116314-0.229102
1-0.1741980.116314-0.229102
2-0.8771720.116314-1.278562
3-0.4999850.116314-0.096270
41.1955300.4287470.230859
50.3467500.020427-0.676320
61.701942-0.1002330.674782

又比如,使用其他列的值对某列的缺失值进行填充:

#使用列1填补列2的缺失值
df[2].fillna(df[0])
0   -0.393415
1   -0.174198
2   -1.278562
3   -0.096270
4    0.230859
5   -0.676320
6    0.674782
Name: 2, dtype: float64

fillna默认会返回新对象,但也可以对现有对象进行就地修改:

df.fillna(0, inplace = True)
df
012
0-0.3934150.0000000.000000
1-0.1741980.0000000.000000
2-0.8771720.000000-1.278562
3-0.4999850.000000-0.096270
41.1955300.4287470.230859
50.3467500.020427-0.676320
61.701942-0.1002330.674782
  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值