如何将一个数据框映射到另一个数据框(Python Pandas)?

5

给定这两个数据框,如何得到预期的输出数据框?

一种冗长的方法是使用iloc循环遍历数据框的行,然后在将df2转换为一个dict后,使用map函数将x和y映射到它们的分数。

这个过程似乎很繁琐,在较大的数据框上运行需要很长时间。希望有更简洁的解决方案。

df1:

ID    A    B    C
1     x    x    y
2     y    x    y
3     x    y    y

df2:

ID    score_x    score_y
1          20         30
2          15         17
3          18         22

输出:

ID    A     B     C
1     20    20    30
2     17    15    17
3     18    22    22

注意:数据框架可能有很多列,并且除了 x 和 y 之外,还会有更多类别(可能在 20 个类别左右)。
谢谢!
3个回答

8

使用 DataFrame.applySeries.map 对列进行操作:

df1.set_index('ID', inplace=True)
df2.set_index('ID', inplace=True)
df2.columns = df2.columns.str.split('_').str[-1]

df1 = df1.apply(lambda x: x.map(df2.loc[x.name]), axis=1).reset_index()

print(df1)
   ID   A   B   C
0   1  20  20  30
1   2  17  15  17
2   3  18  22  22

print(df2)
     x   y
ID        
1   20  30
2   15  17
3   18  22

4

使用mask

df1.set_index('ID', inplace=True)
df2.set_index('ID', inplace=True)

df1.mask(df1=='x',df2['score_x'],axis=0).mask(df1=='y',df2['score_y'],axis=0)

结果:

     A   B   C
ID            
1   20  20  30
2   17  15  17
3   18  22  22

如果有很多列并且它们都以相同的方式命名,您可以使用类似于以下内容的东西:
for e in df2.columns.str.split('_').str[-1]:
     df1.mask(df1==e, df2['score_'+e], axis=0, inplace=True)

1
@jezrael:看一下我的回答添加,虽然我承认它不太优雅。 - Stef
@jezrael 使用 mask 在一个 1000 x 3 的数据框中替换 20 个类别,比使用 apply 快约 10 倍。 - Stef

0

可能有更优雅的方法,但假设您可以枚举类别和列:

import numpy as np

df3 = df1.set_index('ID').join(df2.set_index('ID'), on='ID')
for col in ['A','B','C']:
     for type in ['x','y']:
         df3[col] = np.where(df3[col] == type, df3['score_'+type], df3[col])



>>> df3
     A   B   C  score_x  score_y
ID
1   20  20  30       20       30
2   17  15  17       15       17
3   18  22  22       18       22

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