如果日期在2个日期之间,则Python Pandas列中的总和值

clg*_*lg4 5 python dataframe melt pandas pandas-groupby

我有一个df可以用这个创建的数据框:

data={'id':[1,1,1,1,2,2,2,2],
      'date1':[datetime.date(2016,1,1),datetime.date(2016,1,2),datetime.date(2016,1,3),datetime.date(2016,1,4),
               datetime.date(2016,1,2),datetime.date(2016,1,4),datetime.date(2016,1,3),datetime.date(2016,1,1)],
      'date2':[datetime.date(2016,1,5),datetime.date(2016,1,3),datetime.date(2016,1,5),datetime.date(2016,1,5),
               datetime.date(2016,1,4),datetime.date(2016,1,5),datetime.date(2016,1,4),datetime.date(2016,1,1)],
      'score1':[5,7,3,2,9,3,8,3],
      'score2':[1,3,0,5,2,20,7,7]}
df=pd.DataFrame.from_dict(data)

And looks like this:
   id       date1       date2  score1  score2
0   1  2016-01-01  2016-01-05       5       1
1   1  2016-01-02  2016-01-03       7       3
2   1  2016-01-03  2016-01-05       3       0
3   1  2016-01-04  2016-01-05       2       5
4   2  2016-01-02  2016-01-04       9       2
5   2  2016-01-04  2016-01-05       3      20
6   2  2016-01-03  2016-01-04       8       7
7   2  2016-01-01  2016-01-01       3       7
Run Code Online (Sandbox Code Playgroud)

我需要做的就是为每一个的列score1score2,创造它的SUM值两列score1,并score2分别根据有无usedate之间date1date2usedate通过获取介于date1最小和date2最大之间(包括最小和最大)的所有日期来创建。我用它来创建日期范围:

drange=pd.date_range(df.date1.min(),df.date2.max())    
Run Code Online (Sandbox Code Playgroud)

结果数据框newdf应如下所示:

     usedate  score1sum  score2sum
0 2016-01-01          8          8
1 2016-01-02         21          6
2 2016-01-03         32         13
3 2016-01-04         30         35
4 2016-01-05         13         26
Run Code Online (Sandbox Code Playgroud)

为了清楚起见,在usedate2016年1月1日,score1sum是8,这是通过观察在各行计算df,其中2016年1月1日是与包括之间date1date2,其总和ROW0(5)和ROW8(3)。上usedate2016年1月4日,score2sum是35,这是由寻找中的行计算df,其中2016年1月4日是与包括之间date1date2,其总和ROW0(1),ROW3(0),ROW4(5),ROW5( 2),第6(20)行,第7(7)行。

也许某种groupby,或meltgroupby

Sco*_*ton 5

您可以apply与 lambda 函数一起使用:

df['date1'] = pd.to_datetime(df['date1'])

df['date2'] = pd.to_datetime(df['date2'])

df1 = pd.DataFrame(index=pd.date_range(df.date1.min(), df.date2.max()), columns = ['score1sum', 'score2sum'])

df1[['score1sum','score2sum']] = df1.apply(lambda x: df.loc[(df.date1 <= x.name) & 
                                                            (x.name <= df.date2),
                                                            ['score1','score2']].sum(), axis=1)

df1.rename_axis('usedate').reset_index()
Run Code Online (Sandbox Code Playgroud)

输出:

     usedate  score1sum  score2sum
0 2016-01-01          8          8
1 2016-01-02         21          6
2 2016-01-03         32         13
3 2016-01-04         30         35
4 2016-01-05         13         26
Run Code Online (Sandbox Code Playgroud)