基于两个其他日期之间的日期合并两个数据帧而不使用公共列

P S*_*nce 16 python pandas

我有两个数据帧,我需要根据日期值是否适合两个其他日期进行合并.基本上我需要执行外连接,其中B.event_date位于A.start_date和A.end_date之间.似乎合并和连接总是假设一个公共列,在这种情况下,我没有.

    A                           B
    start_date  end_date        event_date  price
0   2017-03-27  2017-04-20  0   2017-01-20  100
1   2017-01-10  2017-02-01  1   2017-01-27  200

Result 
    start_date  end_date        event_date  price
0   2017-03-27  2017-04-20  
1   2017-01-10  2017-02-01      2017-01-20  100
2   2017-01-10  2017-02-01      2017-01-27  200
Run Code Online (Sandbox Code Playgroud)

Sco*_*ton 21

创建数据和格式到日期时间:

df_A = pd.DataFrame({'start_date':['2017-03-27','2017-01-10'],'end_date':['2017-04-20','2017-02-01']})
df_B = pd.DataFrame({'event_date':['2017-01-20','2017-01-27'],'price':[100,200]})

df_A['end_date'] = pd.to_datetime(df_A.end_date)
df_A['start_date'] = pd.to_datetime(df_A.start_date)
df_B['event_date'] = pd.to_datetime(df_B.event_date)
Run Code Online (Sandbox Code Playgroud)

创建密钥以进行交叉连接:

df_A = df_A.assign(key=1)
df_B = df_B.assign(key=1)
df_merge = pd.merge(df_A, df_B, on='key').drop('key',axis=1)
Run Code Online (Sandbox Code Playgroud)

过滤掉不符合开始日期和结束日期之间事件日期标准的记录:

df_merge = df_merge.query('event_date >= start_date and event_date <= end_date')
Run Code Online (Sandbox Code Playgroud)

加入原始日期范围表并删除键列

df_out = df_A.merge(df_merge, on=['start_date','end_date'], how='left').fillna('').drop('key', axis=1)

print(df_out)
Run Code Online (Sandbox Code Playgroud)

输出:

              end_date           start_date           event_date price
0  2017-04-20 00:00:00  2017-03-27 00:00:00                           
1  2017-02-01 00:00:00  2017-01-10 00:00:00  2017-01-20 00:00:00   100
2  2017-02-01 00:00:00  2017-01-10 00:00:00  2017-01-27 00:00:00   200
Run Code Online (Sandbox Code Playgroud)

  • 由于此连接引起的笛卡尔积,此方法不会导致记录爆炸. (6认同)
  • 这对大型数据集有效吗? (2认同)
  • 对于未来的读者,我已经为更大的数据帧用例添加了一个答案 [here](/sf/answers/3849079531/) (2认同)