Polars中rolling_corr遇null值返回异常结果的问题咨询
Polars滚动自相关含Null值时结果异常的原因分析
问题重现
你创建了两个结构近似的DataFrame,仅df2的lag_a列首行为Null(由a列移位得到),但调用rolling_corr后得到完全不同的结果:
df1的结果0.622047与numpy.corrcoef计算一致df2最后一行得到异常值-0.219851
# df1定义 df1 = pl.DataFrame({'a': [1.06, 1.07, 0.93, 0.78, 0.85], 'lag_a': [1., 1.06, 1.07, 0.93, 0.78]}) # df2定义 df2 = pl.DataFrame({'a': [1., 1.06, 1.07, 0.93, 0.78, 0.85], 'lag_a': [None, 1., 1.06, 1.07, 0.93, 0.78]})
原因剖析
Polars的rolling_corr处理含Null窗口的逻辑是:仅保留窗口内a和lag_a均不为Null的行对,基于这些有效行对计算皮尔逊相关系数。理论上df2最后一行窗口内的5组有效行对与df1的数据集完全一致,结果应相同,但异常值的出现大概率由以下原因导致:
- 旧版本Polars的Null值处理bug:早期版本的滚动相关计算对Null值的过滤逻辑存在缺陷,错误纳入了无效数据或计算逻辑偏差;
- 滚动窗口范围的隐性差异:若未明确指定窗口对齐方式,部分版本可能对含Null的窗口范围计算出现偏移;
- Null值的错误解析:极端情况下Null值被误当作0或其他数值参与计算,导致相关系数反转。
手动验证有效行对的相关系数可确认这一点:
import numpy as np x = [1.06, 1.07, 0.93, 0.78, 0.85] y = [1.0, 1.06, 1.07, 0.93, 0.78] print(np.corrcoef(x, y)[0,1]) # 输出0.622047,与df1结果一致
解决方案
- 升级Polars到最新稳定版本:新版本修复了大量Null值相关的计算bug,能正确过滤无效行对并计算;
- 手动过滤Null值后计算:提前移除含Null的行对,确保计算数据集与
df1一致:df2_filtered = df2.drop_nulls(subset=['a', 'lag_a']) result = df2_filtered.select(pl.rolling_corr('a', 'lag_a', window_size=10, min_periods=5, ddof=1))
内容的提问来源于stack exchange,提问作者jackaixin
相关产品推荐
相关产品推荐

