首页 > 解决方案 > 根据来自其他数据框的匹配历史记录创建 col

问题描述

我有两个数据框,df_a并且df_b

df_a = pd.DataFrame({
    'date_a': [
        datetime.datetime(2020,1,9,1,1,1,1),
        datetime.datetime(2020,1,4,1,1,1,1),
        datetime.datetime(2020,1,1,1,1,1,1),
        datetime.datetime(2020,1,6,1,1,1,1)
    ],
    'ID': ['a', 'a', 'c', 'a']
})

df_b = pd.DataFrame({
    'date_b': [
        datetime.datetime(2020,1,8,1,1,1,1),
        datetime.datetime(2020,1,5,1,1,1,1),
        datetime.datetime(2020,1,5,1,1,1,1)
    ],
    'ID_1': ['a', 'b', 'f'],
    'ID_2': ['d', 'a', 'c']
})

我想创建一个新列 ( V) df_aTrue如果在df_bwheredf_b.ID_1df_b.ID_2匹配df_a.ID AND df_b.date_b小于或等于 中有记录df_a.date_a。结果将如下所示:

df_a
    date_a                      ID  V
0   2020-01-09 01:01:01.000001  a   True
1   2020-01-04 01:01:01.000001  a   False
2   2020-01-01 01:01:01.000001  c   False
3   2020-01-06 01:01:01.000001  a   True

基本上,我想检查每一行df_a是否有历史记录ID。希望这个问题有意义!

标签: pythonpandasdataframematch

解决方案


一种方法是 melt df_b,然后进行交叉合并ID和查询:

unique_id = (df_b.melt('date_b', value_name='ID')
                .drop('variable',axis=1)
                .sort_values('date_b')
                .drop_duplicates('ID'))

(df_a.merge(unique_id,
           on='ID',
           how='left'
          )
     .assign(V=lambda x: x.date_b <= x.date_a)
     .drop('date_b',axis=1)
)

输出:

                      date_a ID      V
0 2020-01-09 01:01:01.000001  a   True
1 2020-01-04 01:01:01.000001  a  False
2 2020-01-01 01:01:01.000001  c  False
3 2020-01-06 01:01:01.000001  a   True

另一种方法是使用merge_asof,但首先您还需要过滤df_b每个 id 中的最小日期:

# unique_id as above
(pd.merge_asof(df_a.sort_values('date_a'), 
              unique_id, 
              left_on='date_a',
              right_on='date_b', 
              by='ID')
   .assign(V=lambda x: x.date_b.notnull())
   .drop('date_b', axis=1)
)

输出:

                      date_a ID      V
0 2020-01-01 01:01:01.000001  c  False
1 2020-01-04 01:01:01.000001  a  False
2 2020-01-06 01:01:01.000001  a   True
3 2020-01-09 01:01:01.000001  a   True

推荐阅读