Pandas Dataframe中的累计值,但在每个新年的特定日期重置为零

ikfrs5lh  于 6个月前  发布在  其他
关注(0)|答案(2)|浏览(71)

我有一个按时间降序排列的数组,索引为Race_IDStudent_ID

Race_ID   Date           Student_ID      Mark     
1         1/10/2023      1               5        
1         1/10/2023      2               8        
1         1/10/2023      3               7        
8         1/10/2023      4               4        
8         1/1/2023       1               9        
8         1/1/2023       2               3        
8         1/1/2023       3               5        
8         1/1/2023       4               10       
2         11/9/2022      1               2        
2         11/9/2022      2               4        
2         11/9/2022      3               9        
3         17/4/2022      5               3        
3         17/4/2022      2               4        
3         17/4/2022      3               3        
3         17/4/2022      4               7        
4         1/3/2022       1               4        
4         1/3/2022       2               9        
5         1/1/2021       1               6        
5         1/1/2021       2               1        
5         1/1/2021       3               8

字符串
我想创建一个新的列Seasonal_Mark,它是每个学生Markcumsum,注意在每年的2月1日,总和被设置为零。所以期望的结果如下所示:

Race_ID   Date           Student_ID      Mark     Seasonal_Mark 
1         1/10/2023      1               5        5
1         1/10/2023      2               8        8
1         1/10/2023      3               7        7
8         1/10/2023      4               4        4
8         1/1/2023       1               9        15 (4+2+9)
8         1/1/2023       2               3        20 (4+9+4+3)
8         1/1/2023       3               5        17 (9+3+5)
8         1/1/2023       4               10       17 (7+10)                  
2         11/9/2022      1               2        6  (4+2)
2         11/9/2022      2               4        17 (4+9+4)
2         11/9/2022      3               9        12 (9+3)
3         17/4/2022      5               3        3
3         17/4/2022      2               4        13 (4+9)
3         17/4/2022      3               3        3
3         17/4/2022      4               7        7
4         1/3/2022       1               4        4
4         1/3/2022       2               9        9
5         1/1/2021       1               6        6
5         1/1/2021       2               1        1
5         1/1/2021       3               8        8


先谢谢你了。

0aydgbwb

0aydgbwb1#

另一种可能的解决方案是,如果日期是2月或更晚(在年份中),则创建一个调整后的年份列,该列对应于日期的年份,如果日期早于2月(在年份中),则对应于年份减1。这个新列随后在groupby中使用。

df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)

m = df['Date'].dt.month
y = df['Date'].dt.year

df.assign(
    Seasonal_Mark = (df.assign(
        adjusted_year = np.where(m >= 2, y, y - 1))
    .sort_values(by='Date')
    .groupby(['Student_ID', 'adjusted_year'])['Mark'].cumsum()))

字符串
输出量:

Race_ID       Date  Student_ID  Mark  Seasonal_Mark
0         1 2023-10-01           1     5              5
1         1 2023-10-01           2     8              8
2         1 2023-10-01           3     7              7
3         8 2023-10-01           4     4              4
4         8 2023-01-01           1     9             15
5         8 2023-01-01           2     3             20
6         8 2023-01-01           3     5             17
7         8 2023-01-01           4    10             17
8         2 2022-09-11           1     2              6
9         2 2022-09-11           2     4             17
10        2 2022-09-11           3     9             12
11        3 2022-04-17           5     3              3
12        3 2022-04-17           2     4             13
13        3 2022-04-17           3     3              3
14        3 2022-04-17           4     7              7
15        4 2022-03-01           1     4              4
16        4 2022-03-01           2     9              9
17        5 2021-01-01           1     6              6
18        5 2021-01-01           2     1              1
19        5 2021-01-01           3     8              8

oiopk7p5

oiopk7p52#

您可以使用自定义的每年2月1日开始的Period作为辅助分组器,为此使用to_periodA-JAN作为频率:

df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)

df['Seasonal_Mark'] = (df.sort_values(by='Date')
                         .groupby(['Student_ID', df['Date'].dt.to_period('A-JAN')])
                       ['Mark'].cumsum()
                      )

字符串
输出量:

Race_ID       Date  Student_ID  Mark  Seasonal_Mark
0         1 2023-10-01           1     5              5
1         1 2023-10-01           2     8              8
2         1 2023-10-01           3     7              7
3         8 2023-10-01           4     4              4
4         8 2023-01-01           1     9             15
5         8 2023-01-01           2     3             20
6         8 2023-01-01           3     5             17
7         8 2023-01-01           4    10             17
8         2 2022-09-11           1     2              6
9         2 2022-09-11           2     4             17
10        2 2022-09-11           3     9             12
11        3 2022-04-17           5     3              3
12        3 2022-04-17           2     4             13
13        3 2022-04-17           3     3              3
14        3 2022-04-17           4     7              7
15        4 2022-03-01           1     4              4
16        4 2022-03-01           2     9              9
17        5 2021-01-01           1     6              6
18        5 2021-01-01           2     1              1
19        5 2021-01-01           3     8              8

相关问题