看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本需求需要找出每行的缺失值,缺失值的位置以缺失值所在的列名为标识,我们来用pandas解决这个问题。
以下是源数据:
from io import StringIO
import pandas as pd
data = '''
团队 第一年 第二年
A1 1
A2 2 16
A3 17
A4 8 20
A5 5
A6 6 8
A7
A8 10 23
'''
df = pd.read_csv(StringIO(data), sep=r'\s+')
df
# ...
团队一列总是有值的,第一年和第二年中有些行的值缺失,需求为新增加一列,展示缺失的列,格式为:
接下来分析一下解决思路。
面对这样的求解每行问题时,我们的思路一般是写一个函数来处理单个行,然后将这个函数用 apply() 应用到所有的行上。
每个行为一个 Series,索引标签为列名,筛选缺失的值再取索引,将索引序列用「和」字符串连接。
我们随机取一个行来编写单行的逻辑,如取索引为6的,因为它有两个缺失内容,方便我们编写代码:
ser = df.iloc[6]
ser
'''
团队 A7
第一年 NaN
第二年 NaN
Name: 6, dtype: object
'''
判断是否为缺失值,得到一个布尔序列:
ser.isna()
'''
团队 False
第一年 True
第二年 True
Name: 6, dtype: bool
'''
来这个布尔序列来抽取数据,筛选出为缺失什的数据:
ser[ser.isna()]
'''
第一年 NaN
第二年 NaN
Name: 6, dtype: object
'''
取结果的索引,就是所有为缺失值的列名序列(是一个索引对象):
ser[ser.isna()].index
# Index(['第一年', '第二年'], dtype='object')
再将这个序列用「和」连接起来:
'和'.join(ser[ser.isna()].index)
# '第一年和第二年'
最后,将以上操作用 apply() 来调用,为了方便操作,我们将字符连接另起一步操作:
(
df.assign(foo=df.apply(lambda ser: ser[ser.isna()].index,axis=1))
.assign(foo=lambda d: d.foo.map('和'.join))
)
'''
团队 第一年 第二年 foo
0 A1 1.0 NaN 第二年
1 A2 2.0 16.0
2 A3 17.0 NaN 第二年
3 A4 8.0 20.0
4 A5 5.0 NaN 第二年
5 A6 6.0 8.0
6 A7 NaN NaN 第一年和第二年
7 A8 10.0 23.0
'''
这样就完成了需求。
(完)
更新时间:2024-08-18 16:08:10 标签:pandas python 缺失值