可能已经问过了,买了,找了30分钟也找不到。
我有两个具有相同列的 pandas 数据框。除了一列之外,这些值都匹配,我想执行完整的外连接,如果两个值都存在,我会得到两个值,如果其中之一存在,则只有一个值。有很多匹配列,所以我更喜欢一个不必为每个匹配列应用某些内容的解决方案。
示例 如果值在两个 df 中,则所有列都相同,只有频率不同:
Gene GeneID Frequency
0 AA 1 10
1 BB 2 15
2 CC 3 12
Gene GeneID Frequency
0 AA 1 20
1 DD 4 29
代码:
import pandas as pd
t1 = [{"Gene": "AA", "GeneID": "1" , "Frequency": 10},
{"Gene": "BB", "GeneID": "2" , "Frequency": 15},
{"Gene": "CC", "GeneID": "3" , "Frequency": 12}]
t2 = [{"Gene": "AA", "GeneID": "1" , "Frequency": 20},
{"Gene": "DD", "GeneID": "4" , "Frequency": 29}]
f1 = pd.DataFrame(t1)
f2 = pd.DataFrame(t2)
m = pd.merge(f1,f2,on=['Gene','Gene'],how='outer')
结果:
Gene GeneID_x Frequency_x GeneID_y Frequency_y
0 AA 1 10.0 1 20.0
1 BB 2 15.0 NaN NaN
2 CC 3 12.0 NaN NaN
3 DD NaN NaN 4 29.0
现在 ID 位于 GeneID_x 或 GeneID_y 中。我想要以下内容:
Gene GeneID Frequency_x Frequency_y
0 AA 1 10.0 20.0
1 BB 2 15.0 NaN
2 CC 3 12.0 NaN
3 DD 4 NaN 29.0
当然,我可以在需要的地方迭代并填充 GeneID,但是还有更多匹配的列。必须有更好的解决方案。我还尝试使用 group by 和aggregate 连接。这是可行的,但是如果只有一个值,我无法看到频率是来自第一个还是第二个 df。
谢谢。
您可以使用:
m = (pd.merge(f1,f2,on='Gene', how='outer')
.rename(columns={'GeneID_x': 'GeneID'})
.assign(GeneID=lambda x: x['GeneID'].fillna(x.pop('GeneID_y'))))
输出:
>>> m
Gene GeneID Frequency_x Frequency_y
0 AA 1 10.0 20.0
1 BB 2 15.0 NaN
2 CC 3 12.0 NaN
3 DD 4 NaN 29.0