pandas.rolling.std() 的结果不一致

Inconsistent results from pandas.rolling.std()

如你所见,代码来自PANDAS官方示例,最后3个数字(5,5,5)的STD应该为0,但示例中没有。

In [1]: s = pd.Series([5,5,6,7,5,5,5])

In [2]: s.rolling(3).std()
Out[2]:
0             NaN
1             NaN
2    5.773503e-01
3    1.000000e+00
4    1.000000e+00
5    1.154701e+00
6    2.580957e-08
dtype: float64

如果我反转数组,结果似乎是正确的。不知道为什么。

In [3]: s[::-1].rolling(3).std()
Out[3]:
6         NaN
5         NaN
4    0.000000
3    1.154701
2    1.000000
1    1.000000
0    0.577350
dtype: float64

您看到的是在使用滚动 window 计算标准偏差时所做的浮点计算中的小舍入误差的结果。在 pandas 的早期版本中,计算标准偏差和方差的代码会自动捕获较小的值并将它们四舍五入为零。在计算小数字的标准偏差(或方差)时发现这会导致问题,因此决定删除自动舍入。这个问题的讨论可以在:

https://github.com/pandas-dev/pandas/issues/37051

更改发生在:

https://github.com/pandas-dev/pandas/pull/40505

在 issue 37051 中,他们提到需要更新文档,但显然这种更改似乎没有反映在当前的在线文档中。

如果您想复制早期版本 pandas 的行为,您可以通过查找任何小值并将它们设置为 0 来手动将小值设置为 0。

In [10]: s_std = s.rolling(3).std()

In [11]: s_std
Out[11]:
0             NaN
1             NaN
2    5.773503e-01
3    1.000000e+00
4    1.000000e+00
5    1.154701e+00
6    2.580957e-08
dtype: float64

In [12]: s_std[s_std < 1e-7] = 0

In [13]: s_std
Out[13]:
0         NaN
1         NaN
2    0.577350
3    1.000000
4    1.000000
5    1.154701
6    0.000000
dtype: float64