如何利用groupby,只对某些行进行计算,保留所有列

2024-05-29 11:20:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用python计算时间序列数据的百分比变化。但我在通过groupby进行计算时遇到了问题,无法在正确的时间段数据上正确地应用计算。 以下是我目前拥有的数据帧:

     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

我试图实现的是在A列上取groupby,如果它不等于'ACTUAL',则取每个组的前4行(在本例中是'TDA\u D5'、'TDA\u U5'和'TD\u BASE',因为我不想从A列取'ACTUAL',并将这4行中的每一行用于每个组的C列值,在一个等式中,C列值为'ACTUAL'来自A列

这意味着我会得到这个等式

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

对于分子的指数6、指数7和指数8,该等式将重复,但对于TDA组D5,分母将分别为指数1、2和3。这也适用于指数19至22,作为TDA组U5的分子,分母仍为指数0至3,指数33至36,作为TD组基数的分子,分母仍为指数0至3。你知道吗

到目前为止我已经试过了

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

我之所以使用/100,是因为我首先尝试测试是否可以将每组的前4条记录应用到一个简单的除以100的公式中,因为我还没有弄清楚如何将它应用到上面提到的等式中实际组的前4条记录中。我能够使用这段代码获得一个series对象,并将每个组的前四条记录(包括“实际”组)除以100,但这就是我现在所处的位置。我不知道我将如何去实现我试图实现的最终公式,在A中每个组的4个记录的子集上,除了“实际”组。 提前谢谢!你知道吗


Tags: 数据baseindex记录指数分子tdgroupby
1条回答
网友
1楼 · 发布于 2024-05-29 11:20:40

你没走那么远。你知道吗

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']

相关问题 更多 >

    热门问题