Python 根据日期和序列号连接两个数据帧?

Python 根据日期和序列号连接两个数据帧?,python,pandas,Python,Pandas,我有两个数据帧,如下所示: df1 = pd.DataFrame({'serialNo':['aaaa','bbbb','cccc','ffff','aaaa','bbbb','aaaa'], 'Name':['Sayonti','Ruchi','Tony','Gowtam','Toffee','Tom','Sayonti'], 'testName': [4402, 3747 ,5555,8754,1234,9876,3602],

我有两个数据帧,如下所示:

df1 = pd.DataFrame({'serialNo':['aaaa','bbbb','cccc','ffff','aaaa','bbbb','aaaa'],
               'Name':['Sayonti','Ruchi','Tony','Gowtam','Toffee','Tom','Sayonti'],
               'testName':   [4402, 3747 ,5555,8754,1234,9876,3602],
               'moduleName':   ['singing', 'dance','booze', 'vocals','drama','paint','singing'],
               'endResult': ['WARNING', 'FAILED', 'WARNING', 'FAILED','WARNING','FAILED','WARNING'],
               'Date':['2018-10-5','2018-10-6','2018-10-7','2018-10-8','2018-10-9','2018-10-10','2018-10-8']})`

df2 = pd.DataFrame({'serialNo':['aaaa','bbbb','aaaa','ffff','xyzy','aaaa'],
               'Food':['Strawberry','Coke','Pepsi','Nuts','Apple','Candy'],
               'Work':   ['AP', 'TC','OD', 'PU','NO','PM'],
               'Date':['2018-10-1','2018-10-6','2018-10-2','2018-10-3','2018-10-5','2018-10-10']
               })
我想加入我可以通过这种方式实现的两个目标:

result = pd.merge(df1,df2,on=['serialNo','Date'],how='inner')

但是我想做一些改变,两个数据帧连接在一起,对日期列进行某种检查,即我想检查df2['date']是否在df1['date']的3天之内。我不想添加一个单独的列来检查这个条件,而是想动态地执行它,以便在加入时检查这个条件。如何实现这一点?

您只能在
serialNo
上加入,然后在加入后过滤结果:

df1['Date'] = pd.to_datetime(df1['Date'])
df2['Date'] = pd.to_datetime(df2['Date'])

result = pd.merge(df1,df2,on='serialNo' ,how='inner')
result = result[result.Date_x.sub(result.Date_y).abs().dt.days.le(3)]
更新 根据下面的评论,删除
.abs()
链接方法,并使用
.between()
而不是
.le()


我不认为你可以,至少不需要创建一个单独的列,或者只对
'serialNo'
进行更大的合并,然后再进行子集设置
pd.merge\u asof
可以让你接近,但它只能保证1:1的合并,所以你不会得到所有的可能性。@Alolz所以创建一个新列来检查日期是唯一的选择,这样我就不会失去所有的可能性了?我认为Chris a的解决方案是实现这一点的最简单方法。如果你真的想让它“即时”完成,请将它包装在一个函数中,在这个函数中传递两个数据帧和天数,然后让它返回子集。是的,我是这样做的@Chris a,因为我无法立即实现它。谢谢我刚刚意识到这是在检查日期是否在日期后3天内,但实际上我想检查日期是否在日期后3天内。所以应该是Date_x+范围(3天)如何实现???@sayo看到更新的答案,这能解决你的问题吗?这很完美:)非常感谢!
result = result[result.Date_x.sub(result.Date_y).dt.days.between(0,3)]