鉴于这两个数据帧,我如何获得预期的输出数据帧?
很长的路要走,就是用iloc
遍历数据帧的行,然后在将map
转换为df2
以将x和y映射到dict
之后使用ID A B C
1 x x y
2 y x y
3 x y y
函数。他们的分数。
这似乎很乏味,并且在大型数据帧上运行将花费很长时间。我希望有一个更清洁的解决方案。
df1:
ID score_x score_y
1 20 30
2 15 17
3 18 22
df2:
ID A B C
1 20 20 30
2 17 15 17
3 18 22 22
输出:
timestamp
请注意:数据框将有很多列,并且类别将不止x和y(可能在20个类别的范围内)。
谢谢!
答案 0 :(得分:8)
将DataFrame.apply
与Series.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
答案 1 :(得分: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)
答案 2 :(得分: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