Pandas rolling apply异常返回全NaN问题求助
解决含NaN列的滚动均值全为NaN问题
核心原因
你遇到的问题源于Pandas rolling() 方法的**min_periods参数默认值等于窗口大小**(此处为50)。这意味着只有当滚动窗口内的非NaN元素数量达到50个时,才会计算均值;否则直接返回NaN。而你的数据中所有滚动窗口内的非NaN元素数量都不足50,因此结果列全为NaN——但单独取前50个元素计算时,自定义函数会忽略NaN直接计算现有值的均值,不受min_periods限制。
直接解决方法
修改rolling()的min_periods参数,设置为你能接受的最小非NaN元素数量(比如设为1,表示只要窗口内有至少1个非NaN值就计算均值):
import pandas as pd import numpy as np mySpecialNumber = 50 df = pd.read_csv('myfile.csv') # 使用内置mean方法并指定min_periods df['rollingAVG'] = df['nanColumn'].rolling(mySpecialNumber, min_periods=1).mean()
这个方法比自定义函数更高效,因为Pandas内置的滚动均值是向量化实现的,性能远优于apply()调用自定义函数。
自定义函数的修正方案
如果你坚持使用自定义nanMean函数,同样需要在rolling()中指定min_periods,同时可以优化函数避免空数组报错(当窗口全为NaN时,arr[~np.isnan(arr)]会是空数组,调用mean()会返回NaN,符合预期):
def nanMean(arr): non_nan = arr[~np.isnan(arr)] return non_nan.mean() if len(non_nan) > 0 else np.nan df['rollingAVG'] = df['nanColumn'].rolling(mySpecialNumber, min_periods=1).apply(nanMean, raw=True)
验证逻辑
你可以先检查每个滚动窗口内的非NaN元素数量,确认是否符合预期:
# 添加一列统计每个窗口内的非NaN数量 df['non_nan_count'] = df['nanColumn'].rolling(mySpecialNumber).count() # 查看前50行的非NaN数量 print(df['non_nan_count'].head(50))
如果输出的数值都小于50,就完全验证了之前的结论——默认min_periods=50导致所有窗口都不满足计算条件,返回NaN。
内容的提问来源于stack exchange,提问作者Kibeth
相关产品推荐
相关产品推荐

