在 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
我有一个 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