Pandas DataFrame中滚动均值/求和无法跳过NA值的问题
Pandas滚动均值/求和跳过NA值的正确实现
你的代码中min_periods=3的设置是问题核心——这个参数要求窗口内必须有至少3个非缺失值才会输出计算结果,导致窗口内存在NA时(非NA数量不足3)直接返回NaN,和你的需求不符。
你需要的逻辑是:
- 仅当窗口包含完整3行时才计算(前两行返回NaN)
- 窗口内只要有非NA值,就计算这些值的均值/求和;全NA时返回NaN
高效实现方案(向量化操作,推荐)
利用Pandas内置的滚动函数,再手动过滤前两行和全NA窗口:
import pandas as pd import numpy as np test = pd.DataFrame({'A': [1, 2, 3, 10, np.nan, 5 , 20, 6, 7, np.nan, np.nan, np.nan]}) # 计算滚动均值 test['rolling_mean'] = test['A'].rolling(3, min_periods=1).mean(skipna=True) # 前两行设为NaN(窗口不足3行) test.loc[:1, 'rolling_mean'] = np.nan # 计算滚动求和 test['rolling_sum'] = test['A'].rolling(3, min_periods=1).sum(skipna=True) # 处理全NA窗口的情况(sum默认返回0,需替换为NaN) test['rolling_sum'] = np.where( test['A'].rolling(3).apply(lambda x: x.notna().any()), test['rolling_sum'], np.nan ) # 前两行设为NaN test.loc[:1, 'rolling_sum'] = np.nan print(test)
自定义逻辑实现(apply方式)
如果需要更灵活的窗口逻辑,可以用apply自定义计算规则:
import pandas as pd import numpy as np test = pd.DataFrame({'A': [1, 2, 3, 10, np.nan, 5 , 20, 6, 7, np.nan, np.nan, np.nan]}) # 滚动均值:仅完整3行窗口计算,非全NA则取非NA值的均值 test['rolling_mean'] = test['A'].rolling(3).apply( lambda x: x.mean(skipna=True) if (len(x) == 3 and x.notna().any()) else np.nan ) # 滚动求和:仅完整3行窗口计算,非全NA则取非NA值的和 test['rolling_sum'] = test['A'].rolling(3).apply( lambda x: x.sum(skipna=True) if (len(x) == 3 and x.notna().any()) else np.nan ) print(test)
结果验证
两种方案都会得到符合需求的结果:
- 前两行(索引0、1)为NaN
- 索引4、5、6、9、10的窗口存在NA,但仍输出非NA值的均值/求和
- 索引11的窗口全为NA,输出NaN
内容的提问来源于stack exchange,提问作者Ankhnesmerira
相关产品推荐
相关产品推荐

