在另一个DataFrame的范围内对Pandas DataFrame列求和

时间:2018-03-16 03:35:55

标签: python pandas numpy dataframe

我有两个DataFrame DF1DF2,我希望在DF1中的列的日期范围内汇总DF2中一列的值。这是我可重复的例子:

DF1的范围从6/14/20137/13/2013,并按时间降序排列。要汇总的列是ab。请注意,同一date可以有多个记录。

list1 = [{'a': 5, 'date': '7/13/2013', 'b': 13},
 {'a': 4, 'date': '7/12/2013', 'b': 14},
 {'a': 7, 'date': '7/12/2013', 'b': 12},
 {'a': 2, 'date': '7/10/2013', 'b': 18},
 {'a': 9, 'date': '7/7/2013', 'b': 17},
 {'a': 6, 'date': '7/5/2013', 'b': 20},
 {'a': 8, 'date': '6/30/2013', 'b': 12},
 {'a': 5, 'date': '6/29/2013', 'b': 13},
 {'a': 3, 'date': '6/25/2013', 'b': 13},
 {'a': 4, 'date': '6/23/2013', 'b': 10},
 {'a': 1, 'date': '6/22/2013', 'b': 16},
 {'a': 6, 'date': '6/20/2013', 'b': 19},
 {'a': 7, 'date': '6/18/2013', 'b': 12},
 {'a': 9, 'date': '6/16/2013', 'b': 15}]

DF1 = pd.DataFrame(list1)

DF2包含每周日期分隔符,应为DF1ab进行汇总。

list2 = [{'datesep': '6/22/2013', 'c': 32},
 {'datesep': '6/29/2013', 'c': 23},
 {'datesep': '7/6/2013', 'c': 44},
 {'datesep': '7/13/2013', 'c': 18},
 {'datesep': '7/20/2013', 'c': 51}]

DF2 = pd.DataFrame(list2)

我想要做的是按原样保留DF1.c,然后汇总DF1.aDF1.b,以便在DF2.datesep分隔符的DF1.date分隔符上汇总这些值1}}。也就是说,DF1.aDF1.b6/16/20136/22/2013(包括两者)的值应该在最近的下一个日期分隔符聚合,即DF2.datesep=6/22/2013行。 7/7/20137/13/2013(包括两者)应该在最近的下一个日期分隔符聚合,即DF2.datesep=7/13/2013行等。因此结果应该是这样的(列顺序不重要) ):

       c       date a_sum  b_sum
0     32  6/22/2013    23     62
1     23  6/29/2013    12     36
2     44   7/6/2013    14     32
3     18  7/13/2013    27     74
4     51  7/20/2013     -      -

我通过list1list2上的循环执行了此操作,但是是否有使用DF1DF2的Pandas / Numpy解决方案?谢谢!

1 个答案:

答案 0 :(得分:1)

首先,您需要将日期字符串转换为实际日期。然后,您可以使用lambda为每行计算a_sum和b_sum。最后将总和df与DF2结合起来:

DF1.date = pd.to_datetime(DF1.date)
DF2['end'] = pd.to_datetime(DF2.datesep)
DF2['start'] = DF2.end.shift(1).fillna(pd.to_datetime('1970-01-01'))
sums = DF2.apply(lambda x: DF1.loc[DF1.date.gt(x.start) & DF1.date.le(x.end)][['a','b']].sum(), axis=1)
sums.columns=['a_sum','b_sum']
pd.concat([DF2[['c','datesep']],sums],1)

    c   datesep a_sum   b_sum
0   32  6/22/2013   23  62
1   23  6/29/2013   12  36
2   44  7/6/2013    14  32
3   18  7/13/2013   27  74
4   51  7/20/2013   0   0