如何按类别列用最近值填充Pandas中的NaN值?
问题描述
现有如下示例DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame({ "Date": ["2022-10-01","2022-10-02","2022-10-03","2022-10-04","2022-10-05","2022-10-06","2022-10-01","2022-10-02","2022-10-03","2022-10-04","2022-10-05","2022-10-06"], "Animal" :["Cat","Cat","Cat","Cat","Cat","Cat","Dog","Dog","Dog","Dog","Dog","Dog"], "Quantity":[np.nan,4,3,5,1,np.nan,6,5,np.nan,np.nan,2,1] })
原始数据展示:
Date Animal Quantity 0 2022-10-01 Cat NaN 1 2022-10-02 Cat 4.0 2 2022-10-03 Cat 3.0 3 2022-10-04 Cat 5.0 4 2022-10-05 Cat 1.0 5 2022-10-06 Cat NaN 6 2022-10-01 Dog 6.0 7 2022-10-02 Dog 5.0 8 2022-10-03 Dog NaN 9 2022-10-04 Dog NaN 10 2022-10-05 Dog 2.0 11 2022-10-06 Dog 1.0
需要按以下规则填充Quantity列的NaN值:
- 优先用同一Animal类别下、该NaN值之前最近的有效值替换;
- 若经过第一步后仍有剩余NaN,用同一Animal类别下、该NaN值之后最近的有效值替换。
尝试过Series.interpolate,但不知道如何按Animal分组处理,求高效实现方法,期望输出如下:
Date Animal Quantity 0 2022-10-01 Cat 4 1 2022-10-02 Cat 4 2 2022-10-03 Cat 3 3 2022-10-04 Cat 5 4 2022-10-05 Cat 1 5 2022-10-06 Cat 1 6 2022-10-01 Dog 6 7 2022-10-02 Dog 5 8 2022-10-03 Dog 5 9 2022-10-04 Dog 5 10 2022-10-05 Dog 2 11 2022-10-06 Dog 1
解决方案
直接利用pandas的分组(groupby)结合向前填充(ffill)和向后填充(bfill)即可高效实现需求,逻辑完全匹配填充规则:
# 按Animal分组,先向前填充(用前面最近有效值),再向后填充剩余NaN(用后面最近有效值) df['Quantity'] = df.groupby('Animal')['Quantity'].ffill().bfill() # 可选:将浮点型转为整型(匹配期望输出格式) df['Quantity'] = df['Quantity'].astype(int)
代码说明:
groupby('Animal'):确保所有填充操作限定在同一动物类别内,不会跨类别取值;ffill():全称forward fill,按顺序用当前NaN之前最近的有效值填充,对应规则1;bfill():全称backward fill,对ffill后剩余的NaN(比如Cat的第0行,前面无有效值),用之后最近的有效值填充,对应规则2;- 最后转整型是为了和期望输出格式一致,若无需转换可省略该步骤。
运行上述代码后即可得到目标结果。
内容的提问来源于stack exchange,提问作者Ewdlam
相关产品推荐
相关产品推荐

