【问题标题】:Pandas Dataframe Merge on 2 Columns Including Conditional If Merge: If Date in df_2 is Between Two Other Dates in df_1Pandas Dataframe 合并 2 列,包括条件 If 合并:如果 df_2 中的日期在 df_1 中的其他两个日期之间
【发布时间】:2018-09-09 15:08:46
【问题描述】:

我有以下示例数据框:

df_1:

from datetime import datetime
import pandas as pd

>>> df_1 = pd.DataFrame( 
 {"SVDiscrep_Merge": ["2081916SAN", "2081242DFW", "2081248ORD","20874CLE", "2081740DEN"],
 "RON_DATE": [datetime(2017,6,1), datetime(2017,6,4), datetime(2017,6,6), datetime(2017,6,7), datetime(2017,6,8)],
 "Next SV1 Date": [datetime(2017,6,4), datetime(2017,6,6), datetime(2017,6,7), datetime(2017,6,8), datetime(2017, 6, 18)]})

>>> df_1

SVDiscrep_Merge     RON_DATE    Next SV1 Date
2081916SAN          6/1/2017    6/4/2017    
2081242DFW          6/4/2017    6/6/2017
2081248ORD          6/6/2017    6/7/2017
20874CLE            6/7/2017    6/8/2017
2081740DEN          6/8/2017    6/18/2017

df_2:

>>> df_2 = pd.DataFrame( 
 {"SVDiscrep_Merge": ["2081916SAN", "2081916SAN", "2081916SAN","2081740DEN"],
 "REPORT_DT": [datetime(2017,6,1), datetime(2017,6,3), datetime(2017,6,4), datetime(2017,6,9)],
 "ColA": ["A", "B", "C", "D"]})

>>> df_2

SVDiscrep_Merge REPORT_DT   ColA
2081916SAN      6/1/2017    A
2081916SAN      6/3/2017    B
2081916SAN      6/4/2017    C
2081740DEN      6/9/2017    D

我想采用以下逻辑:

  1. 当(且仅当)SVDiscrep_Merge 在两个数据帧中相等时,左合并 df_2df_1

  2. REPORT_DT 列是 >= RON_DATE 中的日期和 df_1 中 Next SV1 Date 中的日期。

这是我想要的输出:

SVDiscrep_Merge     RON_DATE    Next SV1 Date  ColA 
2081916SAN          6/1/2017    6/4/2017       A    
2081916SAN          6/4/2017    6/6/2017       B
2081916SAN          6/6/2017    6/7/2017
2081242DFW          6/4/2017    6/6/2017    
2081248ORD          6/6/2017    6/7/2017
20874CLE            6/7/2017    6/8/2017
2081740DEN          6/8/2017    6/18/2017      D

如果我没有那个日期逻辑,我知道如何在 python 代码中进行合并......但是有了那个日期逻辑(在搜索 Google 之后)我不知所措。

【问题讨论】:

  • B 是如何与2081242DFW 排成一行的?
  • 你的数据集是不是太大了,或者我们在谈论一些你不需要超级担心空间的东西?
  • 您确定您的df_2 正确吗?
  • 道歉......你们是对的,我犯了一个错误

标签: python pandas date merge between


【解决方案1】:

您可以在SVDiscrep_Merge 上留下合并,然后使用以下布尔掩码过滤结果:

mask = (((result['RON_DATE'] <= result['REPORT_DT']) 
         & (result['REPORT_DT'] < result['Next SV1 Date'])) 
        | pd.isnull(result['REPORT_DT']))

import datetime as DT 
import pandas as pd

df_1 = pd.DataFrame( 
 {"SVDiscrep_Merge": ["2081916SAN", "2081242DFW", "2081248ORD","20874CLE", "2081740DEN"],
 "RON_DATE": [DT.datetime(2017,6,1), DT.datetime(2017,6,4), DT.datetime(2017,6,6), DT.datetime(2017,6,7), DT.datetime(2017,6,8)],
 "Next SV1 Date": [DT.datetime(2017,6,4), DT.datetime(2017,6,6), DT.datetime(2017,6,7), DT.datetime(2017,6,8), DT.datetime(2017, 6, 18)]})

df_2 = pd.DataFrame( 
 {"SVDiscrep_Merge": ["2081916SAN", "2081916SAN", "2081916SAN","2081740DEN"],
 "REPORT_DT": [DT.datetime(2017,6,1), DT.datetime(2017,6,3), DT.datetime(2017,6,4), DT.datetime(2017,6,9)],
 "ColA": ["A", "B", "C", "D"]})

result = pd.merge(df_1, df_2, on='SVDiscrep_Merge',  how='left')
mask = (((result['RON_DATE'] <= result['REPORT_DT']) 
         & (result['REPORT_DT'] < result['Next SV1 Date'])) 
        | pd.isnull(result['REPORT_DT']))
result = result.loc[mask].drop('REPORT_DT', axis=1)
print(result)

产量

  Next SV1 Date   RON_DATE SVDiscrep_Merge ColA
0    2017-06-04 2017-06-01      2081916SAN    A
1    2017-06-04 2017-06-01      2081916SAN    B
3    2017-06-06 2017-06-04      2081242DFW  NaN
4    2017-06-07 2017-06-06      2081248ORD  NaN
5    2017-06-08 2017-06-07        20874CLE  NaN
6    2017-06-18 2017-06-08      2081740DEN    D

这不是您发布的理想结果,但与逻辑描述一致。

【讨论】:

  • 你完全正确!太感谢了;我确实在我想要的输出表中犯了一个错误
猜你喜欢
  • 1970-01-01
  • 2018-04-04
  • 1970-01-01
  • 2017-09-19
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 2022-11-23
相关资源
最近更新 更多