如何保留原DataFrame并计算忽略NaN的指定窗口大小滚动均值
保留原DataFrame结构的滚动均值计算(取最近N个非空值)
需求说明
需要计算指定窗口大小的滚动均值,满足以下要求:
- 忽略NaN值,取最近N个非空值的均值
- 若当前行值为NaN,均值沿用最近的非空值计算结果
- 必须保留原DataFrame的完整结构,不能删除含NaN的行
原代码通过删除NaN行计算均值,导致丢失原DataFrame中的NaN行,无法满足需求:
df=df.loc[df['value'].notna()] df['rolling_mean']=df['value'].transform(lambda x: x.rolling(2, 0).mean())
预期结果(窗口大小为3):
value rolling_mean3 0 1.0 1.0 1 2.0 2.0 2 6.0 3 3 1.0 3 4 NaN 3 5 5 4
解决方案
核心思路是不删除原DataFrame的NaN行,先提取非空值计算滚动均值,再将结果映射回原DataFrame,最后对NaN行的均值进行前向填充(沿用最近的有效均值)。
代码示例
import pandas as pd # 构造示例数据 df = pd.DataFrame({'value': [1.0, 2.0, 6.0, 1.0, None, 5.0]}) window_size = 3 # 方案1:不足窗口大小时,取现有所有非空值的均值 non_null_rolling = df['value'].dropna().rolling(window=window_size, min_periods=1).mean() df['rolling_mean3'] = non_null_rolling.reindex(df.index).ffill() # 方案2:完全匹配预期结果(不足窗口时取当前行值) # non_null_rolling = df['value'].dropna().rolling(window=window_size, min_periods=window_size).mean().fillna(df['value'].dropna()) # df['rolling_mean3'] = non_null_rolling.reindex(df.index).ffill() print(df)
输出结果
方案1输出:
value rolling_mean3 0 1.0 1.0 1 2.0 1.5 2 6.0 3.0 3 1.0 3.0 4 NaN 3.0 5 5.0 4.0
如果需要完全匹配你给出的预期结果(第1行均值为2.0),可以启用方案2的代码,逻辑是当非空值数量不足窗口大小时,直接取当前行的非空值作为均值。
内容的提问来源于stack exchange,提问作者greenguy
相关产品推荐
相关产品推荐

