如何阻止Pandas rolling将无穷大值转换为NaN?
问题解决思路
核心结论
Pandas的rolling组件目前没有参数可以阻止它将±inf自动转换为NaN,这个行为是内部处理逻辑中硬编码的,无法通过配置直接关闭。
高效替代方案(无需完全自定义滚动函数)
可以利用rolling.apply的raw=False参数,在回调函数中通过窗口索引获取原始分组数据(保留±inf),再执行标准差计算,既满足需求又尽可能保留Pandas的性能优势。
修改后的代码示例:
import numpy as np import pandas as pd def _sd_na(x): return np.nanstd(x, ddof=1) def _custom_stdev_func(x, min_observations, original_col): # 通过窗口索引获取原始列数据(未被rolling转换inf为NaN) window_data = original_col.iloc[x.index] num_samples = np.sum(~np.isnan(window_data)) return _sd_na(window_data) if num_samples >= min_observations else np.nan # 确保数据索引连续(若原索引非连续,重置索引避免iloc取数错误) df = df.reset_index(drop=True) df["sd"] = df.groupby("vid").apply( lambda group: group["col"].rolling( window=50, min_periods=12 ).apply( lambda x: _custom_stdev_func(x, 12, group["col"]), raw=False # 关键:保留Series的索引信息,用于获取原始数据 ) ).reset_index(level=0, drop=True)
方案说明
- 当
raw=False时,rolling.apply传入的参数是带索引的Series,而非纯数值数组; - 通过
x.index可以定位到当前滚动窗口在原始分组数据中的位置,取出的window_data会保留原始的±inf值; - 此时
np.nanstd检测到inf会返回NaN,完全符合你需要的逻辑; - 整个过程依然基于Pandas的rolling框架,性能远优于完全自定义滚动函数。
内容的提问来源于stack exchange,提问作者u2j4
相关产品推荐
相关产品推荐

