Pandas Dataframe 合并 2 列,包括条件 If 合并:如果 df_2 中的日期在 df_1 中的其他两个日期之间
Posted
技术标签:
【中文标题】Pandas Dataframe 合并 2 列,包括条件 If 合并:如果 df_2 中的日期在 df_1 中的其他两个日期之间【英文标题】:Pandas Dataframe Merge on 2 Columns Including Conditional If Merge: If Date in df_2 is Between Two Other Dates in 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
我想采用以下逻辑:
当(且仅当)SVDiscrep_Merge
在两个数据帧中相等时,左合并 df_2
到 df_1
和
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
正确吗?
道歉......你们是对的,我犯了一个错误
【参考方案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
这不是您发布的理想结果,但与逻辑描述一致。
【讨论】:
你完全正确!太感谢了;我确实在我想要的输出表中犯了一个错误以上是关于Pandas Dataframe 合并 2 列,包括条件 If 合并:如果 df_2 中的日期在 df_1 中的其他两个日期之间的主要内容,如果未能解决你的问题,请参考以下文章
将具有相同列/索引的两个 pandas DataFrame 合并为一个 DataFrame
合并具有来自两个不同列的匹配值的 DataFrame - Pandas [重复]
pandas读取多个文件内容为dataframe并合并为一个dataframepandas创建仅有列标签而内容为空的dataframe
在 Python 3.x 中将基于特定列的列和值的两个 DataFrame 与 Pandas 合并
pandas将多个Series对象当成数据行进行垂直合并形成dataframepandas将多个Series对象当做数据列垂直合并形成dataframe