使用 pandas v1.0.1 和 numpy 1.18.1,我想计算时间序列上具有不同窗口大小的滚动均值和标准差。在我正在处理的数据中,某些后续点的值可以是恒定的,这样 - 取决于窗口大小 - 滚动平均值可能等于窗口中的所有值,并且相应的 std 预计为 0。
但是,根据窗口大小,我看到使用相同 df 的不同行为。
MWE:
for window in [3,5]:
values = [1234.0, 4567.0, 6800.0, 6810.0, 6821.0, 6820.0, 6820.0, 6820.0, 6820.0, 6820.0, 6820.0]
df = pd.DataFrame(values, columns=['values'])
df.loc[:, 'mean'] = df.rolling(window, min_periods=1).mean()
df.loc[:, 'std'] = df.rolling(window, min_periods=1).std(ddof=0)
print(df.info())
print(f'window: {window}')
print(df)
print('non-rolling result:', df['values'].iloc[len(df.index)-window:].values.std())
print('')
输出:
window: 3
values mean std
0 1234.0 1234.000000 0.000000
1 4567.0 2900.500000 1666.500000
2 6800.0 4200.333333 2287.053757
3 6810.0 6059.000000 1055.011216
4 6821.0 6810.333333 8.576454
5 6820.0 6817.000000 4.966555
6 6820.0 6820.333333 0.471405
7 6820.0 6820.000000 0.000000
8 6820.0 6820.000000 0.000000
9 6820.0 6820.000000 0.000000
10 6820.0 6820.000000 0.000000
non-rolling result: 0.0
window: 5
values mean std
0 1234.0 1234.000000 0.000000
1 4567.0 2900.500000 1666.500000
2 6800.0 4200.333333 2287.053757
3 6810.0 4852.750000 2280.329732
4 6821.0 5246.400000 2186.267193
5 6820.0 6363.600000 898.332366
6 6820.0 6814.200000 8.158431
7 6820.0 6818.200000 4.118252
8 6820.0 6820.200000 0.400000
9 6820.0 6820.000000 0.000021
10 6820.0 6820.000000 0.000021
non-rolling result: 0.0
正如预期的那样,对于 idx 7,8,9,10 使用 3 的窗口大小,std 为 0。对于窗口大小 5,我希望 idx 9 和 10 产生 0。但是,结果与 0 不同。
如果我为每个窗口大小的最后一个窗口“手动”计算 std(分别使用 idxs 8,9,10 和 6,7,8,9,10),我会得到两种情况下的预期结果 0。
有人知道这里可能是什么问题吗?任何数字警告?
最佳答案
std()
中 pd.rolling
的实现似乎更喜欢高性能而不是数值精度。但是您可以应用标准偏差的 np
版本:
df.loc[:, 'std'] = df.rolling(window, min_periods=1).apply(np.std)
结果:
values std
0 1234.0 0.000000
1 4567.0 1666.500000
2 6800.0 2287.053757
3 6810.0 2280.329732
4 6821.0 2186.267193
5 6820.0 898.332366
6 6820.0 8.158431
7 6820.0 4.118252
8 6820.0 0.400000
9 6820.0 0.000000
10 6820.0 0.000000
现在精度更好。
关于python - Pandas 滚动 std 产生不一致的结果并且与 values.std 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60491544/