如何按Id分组,用上方3行均值填充Pandas DataFrame的NaN值?
解决方案:按分组用上方3行均值填充NaN
需求说明
给定Pandas DataFrame,需按Id列分组,将order_values列的NaN值替换为该位置上方3行数据的均值;若存在连续NaN,后续NaN需用上一个填充后的值参与计算(如示例中1002的第二个NaN,用填充后的33+18+36的均值替换)。
输入示例
import pandas as pd import numpy as np # 构造输入DataFrame data = { 'Id': [1002, 1002, 1002, 1002, 1002, 1002, 1003, 1003, 1003, 1003, 1003, 1004, 1004, 1004, 1004], 'order_values': [45, 36, 18, np.nan, np.nan, 72, 68, 54, 45, np.nan, np.nan, 14, 50, 27, np.nan] } df = pd.DataFrame(data)
实现代码
def fill_nan_with_prev3_mean(series): filled = series.copy() for i in range(len(filled)): if pd.isna(filled[i]): # 取当前位置上方最多3行的数据 prev3 = filled[max(0, i-3):i] # 计算均值并保留两位小数 filled[i] = round(prev3.mean(), 2) return filled # 按Id分组应用填充逻辑 df['order_values'] = df.groupby('Id')['order_values'].apply(fill_nan_with_prev3_mean)
输出结果
执行后得到的DataFrame与示例逻辑一致:
| Id | order_values |
|---|---|
| 1002 | 45.00 |
| 1002 | 36.00 |
| 1002 | 18.00 |
| 1002 | 33.00 |
| 1002 | 29.00 |
| 1002 | 72.00 |
| 1003 | 68.00 |
| 1003 | 54.00 |
| 1003 | 45.00 |
| 1003 | 55.67 |
| 1003 | 51.56 |
| 1004 | 14.00 |
| 1004 | 50.00 |
| 1004 | 27.00 |
| 1004 | 30.33 |
逻辑说明
- 自定义函数
fill_nan_with_prev3_mean处理单个分组的order_values列:- 遍历每个元素,判断是否为NaN;
- 若为NaN,截取当前位置上方最多3行的有效数据(包含已填充的前序NaN值);
- 计算均值并保留两位小数,替换当前NaN。
- 通过
groupby('Id')将数据按分组拆分,应用上述函数后合并结果。
内容的提问来源于stack exchange,提问作者s nandan
相关产品推荐
相关产品推荐

