我正在学习Pandas并陷入一个问题,下面通过示例示例解释该问题。 假设有3个DF。 DF1,DF2和DF3。我想根据DF3 ID和Date列将DF3与DF1以及Df2进行比较,其中Date介于StartDate和EndDate之间,更新DF1和DF2中的计数。
d = {'ID':['51','51','51','52'], 'Count' : ['2', '2', '1', '2'],
'StartDate' : pd.to_datetime(['2018-09-01', '2018-07-01', '2018-08-01', '2018-08-01']),
'EndDate' : pd.to_datetime(['2018-09-30', '2018-07-31', '2018-08-31', '2018-08-31'])}
df1= pd.DataFrame(data=d)
Count EndDate ID StartDate
2 2018-09-30 51 2018-09-01
2 2018-07-31 51 2018-07-01
1 2018-08-31 51 2018-08-01
2 2018-08-31 52 2018-08-01
d = {'ID':['51','52'], 'Count' : ['5', '2'],
'StartDate' : pd.to_datetime(['2018-07-01', '2018-07-01']),
'EndDate' : pd.to_datetime(['2018-09-30', '2018-09-30'])}
df2= pd.DataFrame(data=d)
Count EndDate ID StartDate
5 2018-09-30 51 2018-07-01
2 2018-09-30 52 2018-07-01
d = {'ID':['51','51','51','51','52'], 'Count' : ['1', '1', '1', '1','2'],
'Date' : pd.to_datetime(['2018-09-01', '2018-09-14', '2018-08-14', '2018-07-27','2018-08-13'])}
df3= pd.DataFrame(data=d)
Count Date ID
1 2018-09-01 51
1 2018-09-14 51
1 2018-08-14 51
1 2018-07-27 51
2 2018-08-13 52
The expected output is DF1 and Df2 with updated count-
DF1 -
Count EndDate ID StartDate
2 2018-09-30 51 2018-09-01
1 2018-07-31 51 2018-07-01
1 2018-08-31 51 2018-08-01
2 2018-08-31 52 2018-08-01
DF2-
Count EndDate ID StartDate
4 2018-09-30 51 2018-07-01
2 2018-09-30 52 2018-07-01
由于观察到StartDate-'2018-07-01'和EndDate-'2018-07-31'的DF1计数已更新为1,因为DF3的07月份只有1个条目。 同样,DF2中的总(季度)计数从5更改为4。请帮助我解决这种情况。预先感谢。
答案 0 :(得分:0)
注意:示例代码中的Count
列被指定为字符串-我已将它们转换为整数。
我将以我认为是解决汇总到不同时间段问题的最佳方法开始:使用带有日期索引的resample
函数:
data = df3.set_index('Date')
quarterly = data.resample('Q').sum()
monthly = data.resample('M').sum()
这导致
>>> quarterly
Count
Date
2018-09-30 6
>>> monthly
Count
Date
2018-07-31 1
2018-08-31 3
2018-09-30 2
如果有新数据可用,您甚至可以很容易地更新它:
newdata = pd.DataFrame({'Date': [pd.to_datetime('2019-01-03')], 'Count': [2]}).set_index('Date')
quarterly.add(newdata.resample('Q').sum(), fill_value=0)
如果您确实要按照给定的日期范围来执行问题中的操作,则此功能可以通过简单的方式完成您想要的操作:
def updatecount(rangedf, countdf):
for rowid, row in rangedf.iterrows():
count = countdf.query('ID == @row.ID and @row.StartDate <= Date <= @row.EndDate').Count.sum()
rangedf.loc[rowid, "Count"] += count
您将其称为
updatecount(df1, df3)
updatecount(df2, df3)