【问题标题】:Pandas: union two datasets on multiple column key with condition for matched rowsPandas:将多个列键上的两个数据集与匹配行的条件联合起来
【发布时间】:2020-06-04 05:18:31
【问题描述】:

我正在尝试获取最新的当前数据视图。我在 Pandas 数据框中有传入的新数据,我需要将其与现有数据的另一个数据框合并。我有一个包含关键列的列表(以匹配两个数据帧之间的行)。

我需要一个结果数据帧,其中包含每个数据帧中不存在于另一个数据帧中的所有行(基于键)。但是,当密钥在两个数据帧中时,我需要比较“trantime”列以查看哪个是最新的并使用该行。

设置如下:

import pandas as pd
from datetime import datetime, timedelta

# Use this list of columns to join the 2 dataframes.
key_columns = ['col1','col2']

time = datetime.now()

existing_df = pd.DataFrame(dict(
    col1=[0,1,1,2],
    col2=['a','b','c','b'],
    attr1=['this','is','just','something'],
    trantime=[
        time - timedelta(days=1),
        time,
        time - timedelta(days=2),
        time - timedelta(days=3)
    ]
))

new_df = pd.DataFrame(dict(
    col1=[1,2,2],
    col2=['b','b','c'],
    attr1=['plus','more','stuff'],
    trantime=[
        time - timedelta(days=1),
        time,
        time]
))

# How do I get this:
expected_output_df = pd.DataFrame(dict(
    col1=[0,1,1,2,2],
    col2=['a','b','c','b','c'],
    attr1=['this','is','just','more','stuff'],
    trantime=[
        time - timedelta(days=1),
        time,
        time - timedelta(days=2),
        time,
        time
    ]
))

我尝试使用 isin(),但我无法让它与多个列一起工作。我假设我也会使用 concat() 。我曾尝试使用 merge(),但这会在结果数据框中创建带有“_x”/“_y”后缀的列。

有人可以帮忙吗?提前感谢您的宝贵时间!

【问题讨论】:

    标签: pandas


    【解决方案1】:

    pandas merge ordered 可能会有所帮助,尽管我猜合并也可以做同样的事情:

     existing_df = existing_df.sort_values('trantime')
     new_df = new_df.sort_values('trantime')
    
    res = (pd.merge_ordered(existing_df, new_df, on = key_columns)
           #check if there is a new column
           .assign(attr1_x = lambda x: np.where(x.attr1_x.isna() & (x.attr1_y.notna()),
                                                x.attr1_y,x.attr1_x),
                   #compare time entries to get latest
               trantime_x = lambda x: np.where((x.trantime_x.isna()|x.trantime_x.lt(x.trantime_y)),
                                               x.trantime_y, x.trantime_x
                                              )
              )
           #strip off the last two columns
           .iloc[:,:-2]
          )
    
    res
    
    
    
       col1 col2    attr1_x        trantime_x
    0   0   a       this        2020-06-03 06:59:56.012913
    1   1   b       is          2020-06-04 06:59:56.012913
    2   1   c       just        2020-06-02 06:59:56.012913
    3   2   b       something   2020-06-04 06:59:56.012913
    4   2   c       stuff       2020-06-04 06:59:56.012913
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-24
      • 2013-06-20
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 2021-03-04
      相关资源
      最近更新 更多