Pandas多列合并_asof

7

I have two dataframes:

DF1:

StartDate      Location

2013-01-01     20000002
2013-03-01     20000002
2013-08-01     20000002
2013-01-01     20000003
2013-03-01     20000003
2013-05-01     20000003
2013-01-01     20000043

DF2:

EmpStartDate   Location

2012-12-17     20000002.0 
2013-02-25     20000002.0 
2013-06-26     20000002.0 
2012-09-24     20000003.0 
2013-01-07     20000003.0 
2013-07-01     20000043.0

我希望得到DF1.Location等于DF2.Location且DF2.EmpStartDate小于等于DF1.StartDate的DF2计数。

输出:

StartDate      Location   Count

2013-01-01     20000002   1
2013-03-01     20000002   2
2013-08-01     20000002   3
2013-01-01     20000003   1
2013-03-01     20000003   2
2013-05-01     20000003   2
2013-01-01     20000043   0

我正在使用merge_asof函数,将DF2.EmpStartDate和DF1.StartDate进行匹配,然后按照Location和StartDate进行分组以达到某种目的。但是由于我仅在日期列上合并,所以结果不正确,我需要根据Location和Date两个列来合并数据帧。看起来merge_asof函数不支持在多个列上进行合并操作。那么我该如何在不同Location组的日期列之间进行合并?

2个回答

4

merge_asof 会保持 left DataFrame 的大小,所以它不能将同一行在 left 中与多行在 right 中匹配。

一个简单但可能不太节省内存的计算方法是对 Location 执行一个大型的 merge,然后计算有多少行满足条件: df.EmpStartDate < df.StartDate

df = df1.merge(df2)
(df.assign(Count = df.EmpStartDate < df.StartDate)
   .groupby(['StartDate', 'Location'])
   .Count.sum()
   .astype('int')
   .reset_index())

输出:

   StartDate  Location  Count
0 2013-01-01  20000002      1
1 2013-01-01  20000003      1
2 2013-01-01  20000043      0
3 2013-03-01  20000002      2
4 2013-03-01  20000003      2
5 2013-05-01  20000003      2
6 2013-08-01  20000002      3

merge_asof 只能生成1:1的合并结果,因此我认为这不是您在这里想要的。”-- 您为什么这样说?操作有许多情况可以在“左”数据帧中的多个行上使用相同的数据。 - Nunnsy

2

让我们使用这个:

df1.merge(df2, on='Location')\
   .query('EmpStartDate <= StartDate')\
   .groupby(['StartDate','Location'])['EmpStartDate']\
   .count()\
   .reindex(df1, fill_value=0)\
   .rename('Count')\
   .reset_index()

输出:

   StartDate  Location  Count
0 2013-01-01  20000002      1
1 2013-03-01  20000002      2
2 2013-08-01  20000002      3
3 2013-01-01  20000003      1
4 2013-03-01  20000003      2
5 2013-05-01  20000003      2
6 2013-01-01  20000043      0

我使用reindex时得到了计数为0的结果。 - sks
是的,那些缺失的日期和位置将会被填充为0。如果您不想这样,可以从重新索引中删除“fill_value”参数。 - Scott Boston
我的意思是整个结果集都是0!如果我删除重新索引,我会得到正确的结果。但是,我必须处理任何缺失值的情况。 - sks
我不太理解。如果你移除重新索引,你会得到正确的结果吗?为了获取缺失的位置/日期,你需要生成所有可能的位置和日期列表,然后使用重新索引。 - Scott Boston
是的,如果我删除重新索引,我会得到正确的结果。如果我包括重新索引,所有行的计数都为0。目前数据中没有缺失的位置或日期。所以,我猜它正在重新索引所有行。但是,数据可能每个月都有所变化。因此,我将不得不处理它并编写通用代码。 - sks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接