自定义的月份开始和结束日期

时间:2018-04-18 08:04:02

标签: python pandas

我有一个包含日期和值的数据框。我必须计算每个月的总和值。

i.e., df.groupby(pd.Grouper(freq='M'))['Value'].sum()

但问题出在我的数据集中,该月的开始日期是21,结束于20.有没有办法告诉该组从第21天到第20天的月份到熊猫。

假设我的数据框包含开始和结束日期,

starting_date=datetime.datetime(2015,11,21)
ending_date=datetime.datetime(2017,11,20)

到目前为止我试过了,

starting_date=df['Date'].min()
ending_date=df['Date'].max()

month_wise_sum=[]
while(starting_date<=ending_date):
    temp=starting_date+datetime.timedelta(days=31)
    e_y=temp.year
    e_m=temp.month
    e_d=20
    temp= datetime.datetime(e_y,e_m,e_d)

    month_wise_sum.append(df[df['Date'].between(starting_date,temp)]['Value'].sum())
    starting_date=temp+datetime.timedelta(days=1)

print month_wise_sum

我上面的代码完成了这件事。但仍在等待pythonic方式来实现它。

我最大的问题是为月份切片数据框

例如,

2015-11-21 to 2015-12-20

有没有任何pythonic方法来实现这一目标? 在此先感谢。

例如,将此视为我的数据帧。它包含date_range(datetime.datetime(2017,01,21),datetime.datetime(2017,10,20))的日期 输入:

          Date     Value
0   2017-01-21 -1.055784
1   2017-01-22  1.643813
2   2017-01-23 -0.865919
3   2017-01-24 -0.126777
4   2017-01-25 -0.530914
5   2017-01-26  0.579418
6   2017-01-27  0.247825
7   2017-01-28 -0.951166
8   2017-01-29  0.063764
9   2017-01-30 -1.960660
10  2017-01-31  1.118236
11  2017-02-01 -0.622514
12  2017-02-02 -1.416240
13  2017-02-03  1.025384
14  2017-02-04  0.448695
15  2017-02-05  1.642983
16  2017-02-06 -1.386413
17  2017-02-07  0.774173
18  2017-02-08 -1.690147
19  2017-02-09 -1.759029
20  2017-02-10  0.345326
21  2017-02-11  0.549472
22  2017-02-12  0.814701
23  2017-02-13  0.983923
24  2017-02-14  0.551617
25  2017-02-15  0.001959
26  2017-02-16 -0.537112
27  2017-02-17  1.251595
28  2017-02-18  1.448950
29  2017-02-19 -0.452310
..         ...       ...
243 2017-09-21  0.791439
244 2017-09-22  1.368647
245 2017-09-23  0.504924
246 2017-09-24  0.214994
247 2017-09-25 -3.020875
248 2017-09-26 -0.440378
249 2017-09-27  1.324862
250 2017-09-28  0.116897
251 2017-09-29 -0.114449
252 2017-09-30 -0.879000
253 2017-10-01  0.088985
254 2017-10-02 -0.849833
255 2017-10-03  1.136802
256 2017-10-04 -0.398931
257 2017-10-05  0.067660
258 2017-10-06  1.080505
259 2017-10-07  0.516830
260 2017-10-08 -0.755461
261 2017-10-09  1.367292
262 2017-10-10  1.444083
263 2017-10-11 -0.840497
264 2017-10-12 -0.090092
265 2017-10-13  0.193068
266 2017-10-14 -0.284673
267 2017-10-15 -1.128397
268 2017-10-16  1.029995
269 2017-10-17 -1.269262
270 2017-10-18  0.320187
271 2017-10-19  0.580825
272 2017-10-20  1.001110

[273 rows x 2 columns]

我想像下面那样切割这个数据框

Iter项目-1:

         Date     Value
0  2017-01-21 -1.055784
1  2017-01-22  1.643813
2  2017-01-23 -0.865919
3  2017-01-24 -0.126777
4  2017-01-25 -0.530914
5  2017-01-26  0.579418
6  2017-01-27  0.247825
7  2017-01-28 -0.951166
8  2017-01-29  0.063764
9  2017-01-30 -1.960660
10 2017-01-31  1.118236
11 2017-02-01 -0.622514
12 2017-02-02 -1.416240
13 2017-02-03  1.025384
14 2017-02-04  0.448695
15 2017-02-05  1.642983
16 2017-02-06 -1.386413
17 2017-02-07  0.774173
18 2017-02-08 -1.690147
19 2017-02-09 -1.759029
20 2017-02-10  0.345326
21 2017-02-11  0.549472
22 2017-02-12  0.814701
23 2017-02-13  0.983923
24 2017-02-14  0.551617
25 2017-02-15  0.001959
26 2017-02-16 -0.537112
27 2017-02-17  1.251595
28 2017-02-18  1.448950
29 2017-02-19 -0.452310
30 2017-02-20  0.616847

ITER-2:

         Date     Value
31 2017-02-21  2.356993
32 2017-02-22 -0.265603
33 2017-02-23 -0.651336
34 2017-02-24 -0.952791
35 2017-02-25  0.124278
36 2017-02-26  0.545956
37 2017-02-27  0.671670
38 2017-02-28 -0.836518
39 2017-03-01  1.178424
40 2017-03-02  0.182758
41 2017-03-03 -0.733987
42 2017-03-04  0.112974
43 2017-03-05 -0.357269
44 2017-03-06  1.454310
45 2017-03-07 -1.201187
46 2017-03-08  0.212540
47 2017-03-09  0.082771
48 2017-03-10 -0.906591
49 2017-03-11 -0.931166
50 2017-03-12 -0.391388
51 2017-03-13 -0.893409
52 2017-03-14 -1.852290
53 2017-03-15  0.368390
54 2017-03-16 -1.672943
55 2017-03-17 -0.934288
56 2017-03-18 -0.154785
57 2017-03-19  0.552378
58 2017-03-20  0.096006

ITER-N:

          Date     Value
243 2017-09-21  0.791439
244 2017-09-22  1.368647
245 2017-09-23  0.504924
246 2017-09-24  0.214994
247 2017-09-25 -3.020875
248 2017-09-26 -0.440378
249 2017-09-27  1.324862
250 2017-09-28  0.116897
251 2017-09-29 -0.114449
252 2017-09-30 -0.879000
253 2017-10-01  0.088985
254 2017-10-02 -0.849833
255 2017-10-03  1.136802
256 2017-10-04 -0.398931
257 2017-10-05  0.067660
258 2017-10-06  1.080505
259 2017-10-07  0.516830
260 2017-10-08 -0.755461
261 2017-10-09  1.367292
262 2017-10-10  1.444083
263 2017-10-11 -0.840497
264 2017-10-12 -0.090092
265 2017-10-13  0.193068
266 2017-10-14 -0.284673
267 2017-10-15 -1.128397
268 2017-10-16  1.029995
269 2017-10-17 -1.269262
270 2017-10-18  0.320187
271 2017-10-19  0.580825
272 2017-10-20  1.001110

这样我就可以计算每个月的价值系列总和

[0.7536957367200978, -4.796100620186059, -1.8423374363366014, 2.3780759926221267, 5.753755441349653, -0.01072884830461407, -0.24877912707664018, 11.666305431020149, 3.0772592888909065]

我希望我能彻底解释。

2 个答案:

答案 0 :(得分:5)

为了测试我的解决方案,我生成了一些随机数据,频率是每天但它应该适用于每个频率。

index = pd.date_range('2015-11-21', '2017-11-20')
df = pd.DataFrame(index=index, data={0: np.random.rand(len(index))})

在这里,您看到我作为索引传递了一个日期时间数组。使用日期编制索引可在pandas中添加许多附加功能。您应该使用数据(如果Date列已只包含日期时间值):

df = df.set_index('Date')

然后我会通过将20天减去索引来人为地重新调整数据:

from datetime import timedelta
df.index -= timedelta(days=20)

然后我会将数据重新采样到每月索引,并在同一个月汇总所有数据:

df.resample('M').sum()

结果数据框由每个月的最后一个日期时间编制索引(对我而言:

                    0
2015-11-30  3.191098
2015-12-31  16.066213
2016-01-31  16.315388
2016-02-29  13.507774
2016-03-31  15.939567
2016-04-30  17.094247
2016-05-31  15.274829
2016-06-30  13.609203

但随意重新索引:)

答案 1 :(得分:2)

使用pandas.cut()可以为您提供快速解决方案:

import pandas as pd
import numpy as np

start_date = "2015-11-21"
# As @ALollz mentioned, the month with the original end_date='2017-11-20' was missing.  
# since pd.date_range() only generates dates in the specified range (between start= and end=),
# '2017-11-31'(using freq='M') exceeds the original end='2017-11-20' and thus is cut off.
# the similar situation applies also to start_date (using freq="MS") when start_month might be cut off
# easy fix is just to extend the end_date to a date in the next month or use 
# the end-date of its own month '2017-11-30', or replace end= to periods=25
end_date = "2017-12-20"

# create a testing dataframe
df = pd.DataFrame({ "date": pd.date_range(start_date, periods=710, freq='D'), "value": np.random.randn(710)})

# set up bins to include all dates to create expected date ranges
bins = [ d.replace(day=20) for d in pd.date_range(start_date, end_date, freq="M") ]

# group and summary using the ranges from the above bins
df.groupby(pd.cut(df.date, bins)).sum() 
                              value
date                               
(2015-11-20, 2015-12-20]  -5.222231
(2015-12-20, 2016-01-20]  -4.957852
(2016-01-20, 2016-02-20]  -0.019802
(2016-02-20, 2016-03-20]  -0.304897
(2016-03-20, 2016-04-20]  -7.605129
(2016-04-20, 2016-05-20]   7.317627
(2016-05-20, 2016-06-20]  10.916529
(2016-06-20, 2016-07-20]   1.834234
(2016-07-20, 2016-08-20]  -3.324972
(2016-08-20, 2016-09-20]   7.243810
(2016-09-20, 2016-10-20]   2.745925
(2016-10-20, 2016-11-20]   8.929903
(2016-11-20, 2016-12-20]  -2.450010
(2016-12-20, 2017-01-20]   3.137994
(2017-01-20, 2017-02-20]  -0.796587
(2017-02-20, 2017-03-20]  -4.368718
(2017-03-20, 2017-04-20]  -9.896459
(2017-04-20, 2017-05-20]   2.350651
(2017-05-20, 2017-06-20]  -2.667632
(2017-06-20, 2017-07-20]  -2.319789
(2017-07-20, 2017-08-20]  -9.577919
(2017-08-20, 2017-09-20]   2.962070
(2017-09-20, 2017-10-20]  -2.901864
(2017-10-20, 2017-11-20]   2.873909

# export the result
summary = df.groupby(pd.cut(df.date, bins)).value.sum().tolist()

...

相关问题