根据列的不同将一个数据帧映射到另一个数据帧。

3
我有两个数据框,根据df1的某一列中是否存在df2的值,需要将df2的值复制到df1的另一个特定列。
我尝试通过循环遍历数据框,但由于数据量太大,这需要很长时间。我相信一定有一种“pandaic”的方法可以处理这个问题。
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,还有其他优雅的方法吗?

谢谢!

2个回答

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'})

谢谢!这似乎有效。但在我的实际应用中,我有四列数据,使用这些顺序合并的代码会使它变得相当混乱。 - Maccaroni123

1
这是一种方法:

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
@Maccaroni123 尝试打印 m.groupby('variable').cumcount(),这将为每个组分配一个计数,例如 A,A 得到 0,1,再次 B,B 得到 0,1 - anky
我明白了,每个类别A、B...应该有相同的计数。但是当我设置索引并取消堆叠(.set_index(['variable','k']).unstack(0))时,行数几乎增加了一倍。很奇怪。df1.shape[0]不应该等于n.shape[0]吗? - Maccaroni123
@Maccaroni123 如果可能的话,请在示例中添加更多数据。对于示例数据,它可以正常工作。可以添加另一列或其他内容。 - anky
我找到了错误,是在melt命令中有一列重复了。感谢您的帮助! - Maccaroni123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接