python - Pandas 滚动 std 产生不一致的结果并且与 values.std 不同

标签 python pandas numpy

使用 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/

相关文章:

python - 为什么这个切片示例在 NumPy 中的工作方式与它在标准列表中的工作方式不同?

python - 如何在元组列表中使用 numpy.random.choice?

python - 非常大的 numpy 数组不会引发内存错误。它在哪里生活?

python - 如何处理结果很小的python中的数值积分?

python - 如何将悬停突出显示添加到 Bokeh 步骤图

python - 在 python 中,函数返回的是浅拷贝还是深拷贝?

python - 如何为 Pandas 数据框中的不同组分配唯一 ID?

python - 解析简单数组并将其保存在文件中

python - 将几乎没有或没有异常的名称聚类/分组到 Pandas 中的聚类中

python - pandas:两列的条件滚动和