【问题标题】:Map one dataframe to another depending on column根据列将一个数据框映射到另一个数据框
【发布时间】:2019-07-24 17:40:32
【问题描述】:

我有两个数据框,根据 df1 的哪一列出现来自 df2 的值,必须将来自 df2 的值复制到 df1 的另一个特定列。

我尝试循环遍历数据框,但由于数据量大,它需要很长时间。我确信一定有一些“流行”的方式来做到这一点。

import pandas as pd

data1 = {'A': ['X1', 'Y1'],
        'B': ['X2', 'Y2'],
        'A1': ['NaN','NaN'],
        'B1': ['NaN','NaN'],
        }

data2 = {'AB': ['X1', 'Y2', 'X2','Y1'],
        'D': ['D1', 'D4', 'D3', 'D2'],
        }
df1=pd.DataFrame(data1, columns=['A','B','A1','B1'])
df2=pd.DataFrame(data2, columns=['AB','D'])

如果在 df2 中找到 df1 列 A 的值,则必须将 D 的相应值复制到 A1 列。如果在 df2 中找到 df1 列 B 的值,则必须将 D 的值复制到 B1 等...

有可能 A/B 中的值是 NaN,或者 df2 中没有对应的值。

data1_goal = {'A': ['X1', 'Y1'],
        'B': ['X2', 'Y2'],
        'A1': ['D1', 'D2'],
        'B1': ['D3', 'D4'],
        }
df_goal=pd.DataFrame(data1_goal, columns=['A','B','A1','B1'])

除了遍历 df1 之外,还有其他优雅的方法吗?

谢谢!

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:
     df1.merge(df2, left_on='A', right_on='AB').merge(
         df1.merge(df2, left_on='B', right_on='AB'), 
         on=['A','B'])[['A', 'B', 'D_x','D_y']].rename(
         columns={'D_x': 'A1','D_y':'B1'})
    

    【讨论】:

    • 谢谢!这似乎有效。在我的实际应用程序中,我有四列,我认为使用这些顺序合并会使代码非常混乱。
    【解决方案2】:

    这里有一种方法:

    m=df1.loc[:,['A','B']].melt().merge(df2,left_on='value',right_on='AB').drop('AB',1)
    n=m.assign(k=m.groupby('variable').cumcount()).set_index(['variable','k']).unstack(0)
    df1=df1.mask(df1.eq('NaN'),n.values) #df1.mask(df1.isna(),n.values) if actual NaN
    print(df1)
    

        A   B  A1  B1
    0  X1  X2  D1  D3
    1  Y1  Y2  D2  D4
    

    【讨论】:

    • 也谢谢你。我试图理解你的方法,我想我明白了,但我不太确定 cumcount() 在做什么。
    • @Maccaroni123 尝试打印 m.groupby('variable').cumcount() ,这将为每个组分配一个计数,例如 A,A 得到 0,1 ,再次 B,B 得到 0,1
    • 我明白了,每个类别 A、B.. 应该具有相同的计数。但是,当我设置索引和 unstack (.set_index(['variable','k']).unstack(0)) 时,我的行数几乎是原来的两倍。诡异的。 df1.shape[0] = n.shape[0] 不应该吗?
    • @Maccaroni123 如果可能,请在示例中添加更多数据。适用于示例数据。可能是另一列或其他东西
    • 我发现了错误,在 melt 命令中有一个列两次。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2020-10-04
    • 2018-02-13
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 2018-08-03
    相关资源
    最近更新 更多