Как использовать groupby, выполнять вычисления только для определенных строк и сохранять все столбцы - PullRequest
0 голосов
/ 13 июня 2019

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

     A      B           C           D
0    ACTUAL 2018-03-01  249.498000  0.040000
1    ACTUAL 2018-06-01  251.134000  0.040000
2    ACTUAL 2018-09-01  252.010000  0.037000
3    ACTUAL 2018-12-01  252.723000  0.039000
4    ACTUAL 2019-03-01  254.148000  0.038000
5    TDA_D5 2019-03-01  253.393661  0.038667
6    TDA_D5 2019-06-01  254.329314  0.038229
7    TDA_D5 2019-09-01  254.784295  0.038974
8    TDA_D5 2019-12-01  254.988064  0.040149
9    TDA_D5 2020-03-01  255.158740  0.041696
10   TDA_D5 2020-06-01  255.243512  0.043405
11   TDA_D5 2020-09-01  255.360638  0.045753
12   TDA_D5 2020-12-01  255.445890  0.047833
13   TDA_D5 2021-03-01  255.700028  0.051772
14   TDA_D5 2021-06-01  256.001398  0.054357
15   TDA_D5 2021-09-01  256.347487  0.056077
16   TDA_D5 2021-12-01  256.792392  0.056796
17   TDA_D5 2022-03-01  257.314624  0.057218
18   TDA_D5 2022-06-01  257.922474  0.057385
19   TDA_U5 2019-03-01  253.393661  0.038667
20   TDA_U5 2019-06-01  255.882782  0.036118
21   TDA_U5 2019-09-01  258.415239  0.034246
22   TDA_U5 2019-12-01  261.090022  0.032766
23   TDA_U5 2020-03-01  264.033754  0.031713
24   TDA_U5 2020-06-01  267.157258  0.030939
25   TDA_U5 2020-09-01  270.563024  0.030997
26   TDA_U5 2020-12-01  274.090429  0.031201
27   TDA_U5 2021-03-01  277.877144  0.032869
28   TDA_U5 2021-06-01  281.790593  0.033901
29   TDA_U5 2021-09-01  285.838634  0.034656
30   TDA_U5 2021-12-01  289.992294  0.035058
31   TDA_U5 2022-03-01  294.235605  0.035529
32   TDA_U5 2022-06-01  298.547907  0.036048
33  TD_BASE 2019-03-01  253.393661  0.038667
34  TD_BASE 2019-06-01  255.119961  0.037143
35  TD_BASE 2019-09-01  256.589769  0.036490
36  TD_BASE 2019-12-01  257.949582  0.036184
37  TD_BASE 2020-03-01  259.351461  0.036187
38  TD_BASE 2020-06-01  260.702463  0.036312
39  TD_BASE 2020-09-01  262.093917  0.037062
40  TD_BASE 2020-12-01  263.422911  0.037667
41  TD_BASE 2021-03-01  264.883181  0.039809
42  TD_BASE 2021-06-01  266.351643  0.041000
43  TD_BASE 2021-09-01  267.828346  0.041699
44  TD_BASE 2021-12-01  269.313336  0.041867
45  TD_BASE 2022-03-01  270.806660  0.042033
46  TD_BASE 2022-06-01  272.308363  0.042199

Я пытаюсь добиться того, чтобы взять groupby для столбца A, если он не равен «ACTUAL», взять первые 4 строки каждой группы (в этом случае будет 'TDA_D5', 'TDA_U5' и 'TD_BASE', поскольку я не хочу 'ACTUAL' из столбца A), и использую каждую строку из этих 4 строк для значения C столбца каждой группы в уравнении сзначение столбца C 'ACTUAL' из столбца A.

Это означает, что у меня будет уравнение

y = index-5.column-C / index-0.column-C - 1 * 100

, это уравнение будет повторяться для индекса 6, индекса 7 и индекса 8 длячислитель, но знаменатель будет индекс 1, 2 и 3 соответственно для группы TDA_D5.Затем это также применимо к индексу 19–22 в качестве числителя для группы TDA_U5, при этом знаменатель по-прежнему остается индексом от 0 до 3, а по индексу 33–36 - в качестве числителя для группы TD_BASE, а знаменатель - как индекс от 0 до 3.

Пока что я пробовал код

a.groupby('A')['C'].apply(lambda x: (x.iloc[0:4] / 100)).reset_index()

Я использую / 100, потому что я просто сначала пытаюсь проверить, могу ли я применить первые 4 записи каждой группы к простомуразделите на формулу 100, поскольку мне еще предстоит выяснить, как применить ее к первым 4 записям фактической группы в уравнении, которое я упомянул выше.Я смог использовать этот фрагмент кода, чтобы получить объект серии и получить первые четыре записи каждой группы, включая группу «ACTUAL», для деления на 100, но это то, где я сейчас застрял.Я не знаю, как бы я реализовал возможную формулу, которую я пытаюсь достичь, на подмножестве 4 записей из каждой группы в A, кроме группы «ACTUAL».Заранее спасибо!

1 Ответ

0 голосов
/ 13 июня 2019

Вы были не так далеко.

df[df.A != 'ACTUAL'].groupby('A').apply(lambda x: pd.DataFrame(
                                 (x.iloc[:4].reset_index()['C']/df.iloc[:4]['C'] - 1) * 100))

дает:

                  C
A                  
TDA_D5  0  1.561400
        1  1.272354
        2  1.100867
        3  0.896263
TDA_U5  0  1.561400
        1  1.890936
        2  2.541661
        3  3.310748
TD_BASE 0  1.561400
        1  1.587185
        2  1.817297
        3  2.068107

Или же вы предпочитаете, чтобы метки из столбца A были столбцами:

df[df.A != 'ACTUAL'].groupby('A').apply(lambda x: (x.iloc[:4].reset_index()['C']
                                                   /df.iloc[:4]['C'] - 1) * 100).T

, что дает:

A    TDA_D5    TDA_U5   TD_BASE
C                              
0  1.561400  1.561400  1.561400
1  1.272354  1.890936  1.587185
2  1.100867  2.541661  1.817297
3  0.896263  3.310748  2.068107

Если вы хотите вернуть это обратно в исходный фрейм данных, это немного сложнее, потому что вам придется сохранить исходные индексы. Вы можете сделать:

actual = df[df.A == 'ACTUAL']

out = df[df.A != 'ACTUAL'].groupby('A').apply(
    lambda x: x.iloc[:len(actual)].assign(
        resul=((x.iloc[:len(actual)].reset_index()['C']/
                actual.reset_index()['C'] -1)*100).values)).reset_index(
                    level=0, drop=True)

Это дает:

          A           B           C         D     resul
5    TDA_D5  2019-03-01  253.393661  0.038667  1.561400
6    TDA_D5  2019-06-01  254.329314  0.038229  1.272354
7    TDA_D5  2019-09-01  254.784295  0.038974  1.100867
8    TDA_D5  2019-12-01  254.988064  0.040149  0.896263
9    TDA_D5  2020-03-01  255.158740  0.041696  0.397697
19   TDA_U5  2019-03-01  253.393661  0.038667  1.561400
20   TDA_U5  2019-06-01  255.882782  0.036118  1.890936
21   TDA_U5  2019-09-01  258.415239  0.034246  2.541661
22   TDA_U5  2019-12-01  261.090022  0.032766  3.310748
23   TDA_U5  2020-03-01  264.033754  0.031713  3.889763
33  TD_BASE  2019-03-01  253.393661  0.038667  1.561400
34  TD_BASE  2019-06-01  255.119961  0.037143  1.587185
35  TD_BASE  2019-09-01  256.589769  0.036490  1.817297
36  TD_BASE  2019-12-01  257.949582  0.036184  2.068107
37  TD_BASE  2020-03-01  259.351461  0.036187  2.047414

И теперь вы можете поместить это обратно в исходный фрейм данных благодаря индексу:

df.loc[out.index, 'resul'] = out['resul']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...