You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:40:08