在 Python 中查找分布在不同月份的列的值总和

Find sum of values of a column spread over different months in Python

我有一个 table 看起来像

A B C
2017 9 65
2017 10 72
2017 11 88
2017 12 97
2018 1 85
2018 2 67
2018 3 76
2018 4 51
2018 5 69
2018 6 97
2018 7 101
2018 8 22
2019 1 56
2019 2 34
2019 3 71
2019 4 122
2019 5 167
2019 6 34
2019 7 17
2019 8 99
2019 9 20
2019 10 26
2019 11 39
2019 12 30
2020 1 56
2020 2 34
2020 3 71
2020 4 122
2020 5 167
2020 6 34
2020 7 17
2020 8 99
2020 9 20
2020 10 26
2020 11 39
2020 12 30
2021 1 56
2021 2 34
2021 3 71
2021 4 122
2021 5 167
2021 6 34
2021 7 17
2021 8 99
2021 9 20
2021 10 26
2021 11 39
2021 12 30

现在我想要的是:

A B C D
2017 9 65 890
2017 10 72 890
2017 11 88 890
2017 12 97 890
2018 1 85 890
2018 2 67 890
2018 3 76 890
2018 4 51 890
2018 5 69 890
2018 6 97 890
2018 7 101 890
2018 8 22 890
2019 1 56 715
2019 2 34 715
2019 3 71 715
2019 4 122 715
2019 5 167 715
2019 6 34 715
2019 7 17 715
2019 8 99 715
2019 9 20 715
2019 10 26 715
2019 11 39 715
2019 12 30 715
2020 1 56 715
2020 2 34 715
2020 3 71 715
2020 4 122 715
2020 5 167 715
2020 6 34 715
2020 7 17 715
2020 8 99 715
2020 9 20 715
2020 10 26 715
2020 11 39 715
2020 12 30 715
2021 1 56 715
2021 2 34 715
2021 3 71 715
2021 4 122 715
2021 5 167 715
2021 6 34 715
2021 7 17 715
2021 8 99 715
2021 9 20 715
2021 10 26 715
2021 11 39 715
2021 12 30 715

此处 890 是从 9,2017 到 8,2018 的所有值的总和,715 是从 1,2019 到 12,2019 的所有值的总和,同样,715 是从 1 开始的所有值的总和, 2020 到 12,2020,同样 715 是从 1,2021 到 12,2021 的所有值的总和。为了便于计算,C 列中的数字已取相同,即 2019 年、2020 年和 2021 年分别为(56、34、71、122、167、34、17、99、20、26、39、30)。这些数字可能会有所不同对于每一年以及随后的总和。也就是说,我们可以为 2020 年和 (12,13,14,15,16,17,18,19, 20,21,22,23) 2021 年随后的月份 (1,2,3,4,5,6,7,8,10,11,12)。

现在我的努力:

count_months_in_each_year = data.groupby('CALENDAR_YEAR').agg({'CALMONTH':'count'})

count_months_in_each_year.reset_index(inplace = True)

count_months_in_each_year.rename({'CALMONTH':'Count_of_Months'}, axis =1, inplace = True)

data = pd.merge(data, count_months_in_each_year, on = 'CALENDAR_YEAR', how = 'left', indicator = True )

data.drop(columns = ['_merge'], axis =1 , inplace = True)

现在如何获得值的总和,尤其是在我必须考虑 9,2017 到 8,2018 的情况下,尽管我有计数。 现在基于此可以驱动什么逻辑来概括代码以获得结果。

我也试过这个:

####Compute total number of records - number of records which have count of months < 12

number_ofless_than_12_records =  data.shape[0] - data[data['Count_of_Months']==12].shape[0]

#number_ofless_than_12_records = 144.
#Total records = 576

我们能以某种方式利用它吗?

可以使用pandas滚动window函数https://pandas.pydata.org/docs/user_guide/window.html

df['D'] = df['C'].rolling(window=12).sum()

这将计算当前月份和前 11 行的总和。但是它会在开始时填充 NaN 值,直到有足够的月份可以回头看。

所以我们可以向上移动 11 行以获得想要的结果。

df['D'] = df['D'].shift(-11)

如果您不想在末尾使用任何 NaN,您可以对其进行插值或填充。

df['D'] = df['D'].interpolate()

我认为您正在寻找的是将 12 行和 transform 与组总和组成的组:

df['D'] = df.groupby(df.index // 12)['C'].transform('sum')
       A   B    C    D
0   2017   9   65  890
1   2017  10   72  890
2   2017  11   88  890
3   2017  12   97  890
4   2018   1   85  890
5   2018   2   67  890
6   2018   3   76  890
7   2018   4   51  890
8   2018   5   69  890
9   2018   6   97  890
10  2018   7  101  890
11  2018   8   22  890
12  2019   1   56  715
13  2019   2   34  715
14  2019   3   71  715
15  2019   4  122  715
16  2019   5  167  715
17  2019   6   34  715
18  2019   7   17  715
19  2019   8   99  715
20  2019   9   20  715
21  2019  10   26  715
22  2019  11   39  715
23  2019  12   30  715
24  2020   1   56  715
25  2020   2   34  715
26  2020   3   71  715
27  2020   4  122  715
28  2020   5  167  715
29  2020   6   34  715
30  2020   7   17  715
31  2020   8   99  715
32  2020   9   20  715
33  2020  10   26  715
34  2020  11   39  715
35  2020  12   30  715
36  2021   1   56  715
37  2021   2   34  715
38  2021   3   71  715
39  2021   4  122  715
40  2021   5  167  715
41  2021   6   34  715
42  2021   7   17  715
43  2021   8   99  715
44  2021   9   20  715
45  2021  10   26  715
46  2021  11   39  715
47  2021  12   30  715