示例数据:
df1 = pd.DataFrame({
'a': [1, 6, 3, 9],
'b': ['A', 'B', 'C', 'D'],
'c': [10, 20, 30, 40],
'd': [100, 200, 300, 400]
})
df2 = pd.DataFrame({
'm': [1, 5, 3, 7],
'n': [2, 6, 8, 4],
'o': [9, 10, 11, 12]
})
要求:
df1['a']
可以出现在 的任何地方。无论在哪里找到匹配项,df2
我都想返回。df2['m']
经过一些谷歌搜索和 chatGpt 之后,我发现融合df2
和合并df1
很有用,只是它不会检查是否匹配df2['m']
。
代码:
df2_melted = df2.melt(id_vars=['m'], value_vars=['n', 'o'])
merged_df = df1.merge(df2_melted, left_on='a', right_on='value', how='left')
df1['e'] = merged_df['m']
print(df1)
输出:
a b c d e
1 A 10 100 NaN # df1['a'] == df2['m']
6 B 20 200 5.0 # df1['a'] == df2['n']
3 C 30 300 NaN # df1['a'] == df2['m']
9 D 40 400 1.0 # df1['a'] == df2['o']
所需输出:
a b c d e
1 A 10 100 1
6 B 20 200 5
3 C 30 300 3
9 D 40 400 1
如果在融化时df2['m']
也可以添加到value_vars
,那么问题就解决了。我试过了,没用。然后检查了文档,发现无论 中有什么id_vars
,剩余的或剩余的子集都可以成为 的一部分value_vars
。所以这种方法可能不正确,或者我遗漏了一些东西。
然后我想,如果df1['a']
匹配df2['m']
,那么df1['e'] == df1['a'] == df2['m']
。因此,只需NaN
用替换值df1['a']
就可以了,而且它有效。但必须将列转换为 int;因为NaN
,它已更改为浮点数。
工作完整代码:
df2_melted = df2.melt(id_vars=['m'], value_vars=['n', 'o'])
merged_df = df1.merge(df2_melted, left_on='a', right_on='value', how='left')
df1['e'] = merged_df['m']
df1['e'] = (df1['e'].fillna(df1['a'])).astype(int)
似乎即使它是一个可行的解决方案,它也没有必要那么复杂:“尝试任何解决方案:在继续进行时添加更多代码来解决问题,而不改变初始解决方案”。
还有其他更好的方法可以满足我的要求吗?
PS1:在上面的例子中,df1 和 df2 不强制具有相同的行数。
只需将该列复制
m
为之前的新列melt
(也可map
用于代替merge
):变体为
merge
:输出: