【问题标题】:Match two separate dataframes to a larger dataframe based on matching values (In Python)根据匹配值将两个单独的数据帧匹配到更大的数据帧(在 Python 中)
【发布时间】:2021-08-21 07:35:46
【问题描述】:

我有 1 个大数据框和 2 个较小的数据框,我想根据某些标准在其中追加/匹配。

数据

df1(大数据框)

id  Date    pp  pos
aa  q122    200 10
aa  q222    200 10
bb  q322    500 5
bb  q422    500 5
cc  q122    100 2
cc  q222    100 2

df2

name    date1   count1  pp1
aa      q122    3       30
aa      q222    5       10

df3

ex  date2   count2  pp2
cc  q122    3       30
cc  q222    5       10

希望

id  Date    pp  pos name    date1   count1  pwr1    ex  date2   count2  pwr2
aa  q122    200 10  aa      q122    3       30      NaN NaN     0       0
aa  q222    200 10  aa      q222    5       10      NaN NaN     0       0
bb  q322    500 5   NaN     NaN     0       0       NaN NaN     0       0
bb  q422    500 5   NaN     NaN     0       0       NaN NaN     0       0
cc  q122    100 2   NaN     NaN     0       0       cc  q122    3       30
cc  q222    100 2   NaN     NaN     0       0       cc  q222    5       10
                                
                                

逻辑: 我根据“名称”和“前”值是否匹配单个数据框 “id”值以及“日期”

正在做

df1['id'] = df1['name'].combine_first(df1['ex'])


out = df2.merge(df1, on=['id', 'date'], how='outer')

但是对如何合并第三个数据框有点迷茫 任何建议表示赞赏

【问题讨论】:

    标签: python pandas numpy


    【解决方案1】:

    我们可以链接merge操作:

    out = (
        df1.merge(
            df2, left_on=['id', 'Date'], right_on=['name', 'date1'], how='outer'
        ).merge(
            df3, left_on=['id', 'Date'], right_on=['ex', 'date2'], how='outer'
        )
    )
    

    out:

       id  Date   pp  pos name date1  count1   pp1   ex date2  count2   pp2
    0  aa  q122  200   10   aa  q122     3.0  30.0  NaN   NaN     NaN   NaN
    1  aa  q222  200   10   aa  q222     5.0  10.0  NaN   NaN     NaN   NaN
    2  bb  q322  500    5  NaN   NaN     NaN   NaN  NaN   NaN     NaN   NaN
    3  bb  q422  500    5  NaN   NaN     NaN   NaN  NaN   NaN     NaN   NaN
    4  cc  q122  100    2  NaN   NaN     NaN   NaN   cc  q122     3.0  30.0
    5  cc  q222  100    2  NaN   NaN     NaN   NaN   cc  q222     5.0  10.0
    

    使用DataFrame.fillnaDataFrame.rename 通过用0 填充某些列并向下转换为int(如果可能)并修改列名来匹配精确的输出:

    out = (
        df1.merge(
            df2, left_on=['id', 'Date'], right_on=['name', 'date1'], how='outer'
        ).merge(
            df3, left_on=['id', 'Date'], right_on=['ex', 'date2'], how='outer'
        ).rename(
            columns={'pp1': 'pwr1', 'pp2': 'pwr2'}
        ).fillna(
            {'count1': 0, 'pwr1': 0, 'count2': 0, 'pwr2': 0}, downcast='infer'
        )
    )
    

    out:

       id  Date   pp  pos name date1  count1  pwr1   ex date2  count2  pwr2
    0  aa  q122  200   10   aa  q122       3    30  NaN   NaN       0     0
    1  aa  q222  200   10   aa  q222       5    10  NaN   NaN       0     0
    2  bb  q322  500    5  NaN   NaN       0     0  NaN   NaN       0     0
    3  bb  q422  500    5  NaN   NaN       0     0  NaN   NaN       0     0
    4  cc  q122  100    2  NaN   NaN       0     0   cc  q122       3    30
    5  cc  q222  100    2  NaN   NaN       0     0   cc  q222       5    10
    

    数据帧和导入:

    import pandas as pd
    
    df1 = pd.DataFrame({
        'id': ['aa', 'aa', 'bb', 'bb', 'cc', 'cc'],
        'Date': ['q122', 'q222', 'q322', 'q422', 'q122', 'q222'],
        'pp': [200, 200, 500, 500, 100, 100],
        'pos': [10, 10, 5, 5, 2, 2]
    })
    
    df2 = pd.DataFrame({
        'name': ['aa', 'aa'],
        'date1': ['q122', 'q222'],
        'count1': [3, 5],
        'pp1': [30, 10]
    })
    
    df3 = pd.DataFrame({
        'ex': ['cc', 'cc'],
        'date2': ['q122', 'q222'],
        'count2': [3, 5],
        'pp2': [30, 10]
    })
    

    【讨论】:

    • 谢谢你让我试试这个建议 - 什么是沮丧的推断?这只是填充剩余的列 w 值吗
    • NaN 是 float 类型(并且列必须是单一类型)。如果您只是fillna,您最终会得到0.0(浮点数),因为该列包含整数,这表示将大小(如果可能)减少到支持的最小类型。在这种情况下,这会给你int。如果您的实际数据是浮点类型,您可以跳过它。 @林恩
    • 好的,这是有道理的-谢谢你的知识
    【解决方案2】:

    分两个阶段进行:

    merged_1 = pd.merge(df1, df2, left_on=["id", "Date"], right_on=["name", "date1"], how="outer")
    merged = pd.merge(merged_1, df3, left_on=["id", "Date"], right_on=["ex", "date2"], how="outer")
    
    >>> merged
       id  Date   pp  pos name date1  count1   pp1   ex date2  count2   pp2
    0  aa  q122  200   10   aa  q122     3.0  30.0  NaN   NaN     NaN   NaN
    1  aa  q222  200   10   aa  q222     5.0  10.0  NaN   NaN     NaN   NaN
    2  bb  q322  500    5  NaN   NaN     NaN   NaN  NaN   NaN     NaN   NaN
    3  bb  q422  500    5  NaN   NaN     NaN   NaN  NaN   NaN     NaN   NaN
    4  cc  q122  100    2  NaN   NaN     NaN   NaN   cc  q122     3.0  30.0
    5  cc  q222  100    2  NaN   NaN     NaN   NaN   cc  q222     5.0  10.0
    

    【讨论】:

      【解决方案3】:

      必须显示多个对象 ID。?

      如果不是,我会使用加入。代码如下

      df1.set_index('id').join(df2.set_index('name')).join(df3.set_index('ex'))
      

      【讨论】:

        猜你喜欢
        • 2016-07-01
        • 2021-05-12
        • 2018-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-24
        • 1970-01-01
        相关资源
        最近更新 更多