看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在做数据清洗操作中,为了让有部分缺失值(所谓的空值)有数据可用,我们会采取填充的办法,其中一个最为常见的方法就是为平均法,就是有平均数插补。在本例中,我们不是简单地将整个列的平均数据填充在缺失位上,而是考虑了它所在组的情况,即填充它所在组的平均值。
我们先来构造数据,在 Q1 列的 C 和 A 两个组上分别创造一个缺失值:
import pandas as pd
df = pd.read_csv('https://gairuo.com/file/data/team.csv')
# 创建缺失值
# 创建缺失值
df = df.head(10).loc[:,'name':'Q1']
df.loc[(1, 2), 'Q1'] = None
df
'''
name team Q1
0 Liver E 89.0
1 Arry C NaN
2 Ack A NaN
3 Eorge C 93.0
4 Oah D 65.0
5 Harlie C 24.0
6 Acob B 61.0
7 Lfie A 9.0
8 Reddie D 64.0
9 Oscar A 77.0
'''
现在我们需要将这两个缺失值按其所在组的平均值进行填充。
我们可以写一个函数,传入一个数据行,注意这里必须是行方面数据,否则拿不到数据所在的分组(team 值),然后通过分组值来取当前分组的平均值,最后用 fillna 填充这个平均值。
最后使用 apply 调用以上函数,注意调用时传入 axis=1,因为函数要求传入的是一个行数据。
根据解决问题有思路,我们先编写函数,因为逻辑相对简单,在这里我们用 lambda,变量 x 是传入的一行数据,对这行 fillna 填充缺失值,填充的值为分组计算后的平均值序列中的对应分组的值。
fun = lambda x: x.fillna(df.groupby('team').Q1.mean()[x.team])
最后应用以上函数:
df.apply(lambda x: fun(x), axis=1)
# 或者一行代码
df.apply(lambda x: x.fillna(df.groupby('team').Q1.mean()[x.team]), axis=1)
# 还可以用 at 的取平均值
df.apply(lambda x: x.fillna(df.groupby('team').mean().at[x.team, 'Q1']), axis=1)
'''
name team Q1
0 Liver E 89.0
1 Arry C 58.5
2 Ack A 43.0
3 Eorge C 93.0
4 Oah D 65.0
5 Harlie C 24.0
6 Acob B 61.0
7 Lfie A 9.0
8 Reddie D 64.0
9 Oscar A 77.0
'''
这样,就完成了需求。最后,我们变换思路,用 transform 和 mask 也可以实现
mapping = df.Q1.groupby(df.team).transform(lambda x: x.mean())
mapping
'''
0 89.0
1 58.5
2 43.0
3 58.5
4 64.5
5 58.5
6 61.0
7 43.0
8 64.5
9 43.0
Name: Q1, dtype: float64
'''
# 替换
df.assign(Q1=df.Q1.mask(df.Q1.isna(), mapping))
(完)
更新时间:2024-08-18 15:37:16 标签:pandas python 缺失值