Расчет простых скользящих средних панд для цикла - PullRequest
2 голосов
/ 09 ноября 2019

В настоящее время я пытаюсь вычислить простое скользящее среднее для набора данных из нескольких акций. Я пробую код только в двух компаниях (и 4 дня) для простоты, чтобы заставить его работать, но, кажется, есть некоторая проблема с выводом. Ниже мой код.

for index, row in df3.iloc[4:].iterrows():
    if df3.loc[index,'CompanyId'] == df3.loc[index-4,'CompanyId']:
        df3['SMA4'] = df3.iloc[:,1].rolling(window=4).mean()
    else:
        df3['SMA4'] = 0

А вот вывод: Вывод

Кадр данных отсортирован по дате и идентификатору компании. Итак, что должно произойти, это то, что когда идентификатор компании не равен, как указано в коде, результат должен быть нулевым, поскольку я не могу рассчитать скользящее среднее двух разных компаний. Вместо этого он выводит скользящее среднее по обеим компаниям, как в строке 7,8,9.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2019

Хотя ansev и прав, что вам следует использовать специализированную функцию, потому что ручные циклы намного медленнее, я хочу показать, почему ваш код не работал: и в ветви if, и в ветви else весь столбец SMA4 получает назначение(df3['SMA4']), и потому что при последнем запуске цикла, оператор if равен true, поэтому оператор else не имеет никакого эффекта, а SMA4 никогда не равен 0. Итак, чтобы исправить это, можно сначала создать столбец, заполненныйскользящие средние (обратите внимание, что это не цикл for):

df3['SMA4'] = df3.iloc[:,1].rolling(window=4).mean()

И затем вы запускаете цикл, чтобы установить недопустимые строки в 0 (хотя nan будет лучше. Я сохранил в других ошибках, предполагая, чточто числа в ответе ансева верны):

for index, row in df3.iloc[4:].iterrows(): 
    if df3.loc[index,'CompanyId'] != df3.loc[index-4,'CompanyId']: 
        df3.loc[index,'SMA4'] = 0 

Вывод (вероятно, все еще глючит):

    CompanyId  Price   SMA4
0           1     75    NaN
1           1     74    NaN
2           1     77    NaN
3           1     78  76.00
4           1     80  77.25
5           1     79  78.50
6           1     80  79.25
7           2     10   0.00
8           2      9   0.00
9           2     12   0.00
10          2     11   0.00
11          2     11  10.75
12          2      8  10.50
13          2      9   9.75
14          2      8   9.00
15          2      8   8.25
16          2     11   9.00
0 голосов
/ 09 ноября 2019

Использование groupby.rolling

df['SMA4']=df.groupby('CompanyId',sort=False).rolling(window=4).Price.mean().reset_index(drop='CompanyId')
print(df)

    CompanyId  Price   SMA4
0           1     75    NaN
1           1     74    NaN
2           1     77    NaN
3           1     78  76.00
4           1     80  77.25
5           1     79  78.50
6           1     80  79.25
7           0     10    NaN
8           0      9    NaN
9           0     12    NaN
10          0     11  10.50
11          0     11  10.75
12          0      8  10.50
13          0      9   9.75
14          0      8   9.00
15          0      8   8.25
16          0     11   9.00
...