Come eseguire la somma mobile su dataframe panda con group by solo per gli ultimi 365 giorni

Aug 23 2020

Tentativo di calcolare una somma mobile su p_id solo per gli ultimi 365 giorni, creando una nuova colonna che contiene questa somma mobile. Il dataframe con la nuova colonna dovrebbe essere simile a questo:

Date        p_id    points          roll_sum
                                
2016-07-29  57        11            11
2016-08-01  57        9             20
2017-01-12  57        5             25
2017-10-23  57        18            23
2018-03-03  57        0             18
2018-03-06  57        4             22
2019-03-16  57        3             3
1997-04-07  12        50            50
1997-04-09  12        32            82
1998-02-11  12        3             85
1998-05-12  12        0             3
1999-05-22  12        0             3
1999-05-29  12        15            18
2000-07-20  12        2             2
2002-10-27  12        17            19

Ricevo l'errore "La finestra deve essere un numero intero" quando utilizzo questo:

df.groupby(['Date', 'p_id'])['points'].rolling('365D', min_periods=1).sum()

o questo:

df.reset_index(level=0).set_index('Date').groupby('p_id').points.rolling('365D').sum()

Ho provato a cercare su SO, ho ottenuto una risposta simile alla mia ma utilizzava comandi ridondanti per python 2.x

Il data frame può essere ricreato usando il codice:

dates = ['2016-07-29',
'2016-08-01',
'2017-01-12',
'2017-10-23',
'2018-03-03',
'2018-03-06',
'2019-03-16',
'1997-04-07',
'1997-04-09',
'1998-02-11',
'1998-05-12',
'1999-05-22',
'1999-05-29',
'2000-07-20',
'2002-10-27']


pid = [57,57,57,57,57,57,57,12,12,12,12,12,12,12,12]

points = [11,9 ,5 ,18,0 ,4 ,3 ,50,32,3 ,0 ,0 ,15,2 ,17]

roll_sum = [11,20,25,23,18,22,3 ,50,82,85,3 ,3 ,18,2 ,19]

df = pd.DataFrame({'Date': dates,
            'p_id': pid,
            'points':points,
            'roll_sum':roll_sum})

Risposte

1 anon01 Aug 23 2020 at 01:10

puoi aggiungerlo come una serie se l'indice del dataframe e roll_sumcorrisponde; qui l'indice include"p_id", "Date"

df["Date"] = df.Date.astype("datetime64")
roll_calc = df.groupby("p_id").rolling('365D', on="Date")["points"].sum()
df = df.set_index(["p_id", "Date"])
df["roll_sum_calc"] = roll_calc

produzione:

                 points  roll_sum  roll_sum_calc
p_id Date
57   2016-07-29      11        11           11.0
     2016-08-01       9        20           20.0
     2017-01-12       5        25           25.0
     2017-10-23      18        23           23.0
     2018-03-03       0        18           18.0
     2018-03-06       4        22           22.0
     2019-03-16       3         3            3.0
12   1997-04-07      50        50           50.0
     1997-04-09      32        82           82.0
     1998-02-11       3        85           85.0
     1998-05-12       0         3            3.0
     1999-05-22       0         3            0.0
     1999-05-29      15        18           15.0
     2000-07-20       2         2            2.0
     2002-10-27      17        19           17.0
1 HenryYik Aug 23 2020 at 00:56

Usa set_indexsulle colonne corrispondenti e jointorna al rollingrisultato:

s = df.set_index("Date").groupby('p_id')['points'].rolling('365D', min_periods=1).sum()

print (df.set_index(["p_id","Date"]).join(s, rsuffix="_rolling"))

                 points  roll_sum  points_rolling
p_id Date                                        
57   2016-07-29      11        11            11.0
     2016-08-01       9        20            20.0
     2017-01-12       5        25            25.0
     2017-10-23      18        23            23.0
     2018-03-03       0        18            18.0
     2018-03-06       4        22            22.0
     2019-03-16       3         3             3.0
12   1997-04-07      50        50            50.0
     1997-04-09      32        82            82.0
     1998-02-11       3        85            85.0
     1998-05-12       0         3             3.0
     1999-05-22       0         3             0.0
     1999-05-29      15        18            15.0
     2000-07-20       2         2             2.0
     2002-10-27      17        19            17.0