Pandas Rolling Std дает противоречивые результаты и отличается от values.std - PullRequest
5 голосов
/ 02 марта 2020

Используя pandas v1.0.1 и numpy 1.18.1, я хочу вычислить скользящее среднее и стандартное отклонение для разных размеров окна во временном ряду. В данных, с которыми я работаю, значения могут быть постоянными для некоторых последующих точек, так что - в зависимости от размера окна - скользящее среднее может быть равно всем значениям в окне, и ожидается, что соответствующее стандартное значение будет равно 0.

Однако я вижу другое поведение при использовании одного и того же коэффициента в зависимости от размера окна.

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

Как и ожидалось, std равен 0 для idx 7,8,9,10 с использованием размера окна 3. Для размера окна 5 я бы ожидал, что idx 9 и 10 приведут к 0. Однако результат отличается от 0.

Если я вычислю стандартное значение 'вручную' для последнего окна каждого размера окна (используя idxs 8,9,10 и 6,7,8,9,10 соответственно), я получу ожидаемый результат 0 для обоих случаев.

У кого-нибудь есть идея, в чем может быть проблема? Любые численные предостережения?

1 Ответ

1 голос
/ 02 марта 2020

Кажется, что реализация 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

Теперь точность лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...