Python pandas:将多个列替换为与另一个数据帧中的多个列匹配的值

Ste*_*ane 7 python pandas

我搜索了很多答案,最接近的问题是比较两个不同的pandas数据帧的2列,如果相同的插入1到另一个Python,但这个人的特殊问题的答案是一个简单的合并,它没有回答这个问题一般来说.

我有两个大型数据帧,df1(通常约为1000万行)和df2(约1.3亿行).我需要根据匹配两个df2列的两个df1列,使用三列df2中的值更新三列df1中的值.df1的顺序必须保持不变,并且只有具有匹配值的行才会更新.

这就是数据帧的样子:

df1

chr    snp  x    pos a1 a2
1  1-10020  0  10020  G  A    
1  1-10056  0  10056  C  G    
1  1-10108  0  10108  C  G
1  1-10109  0  10109  C  G    
1  1-10139  0  10139  C  T
Run Code Online (Sandbox Code Playgroud)

请注意,并不总是"snp"的值是chr-pos的情况,它可能需要许多其他值而没有链接到任何列(如rs1234,indel-6032等)

df2

ID           CHR   STOP  OCHR  OSTOP
rs376643643    1  10040     1  10020
rs373328635    1  10066     1  10056    
rs62651026     1  10208     1  10108    
rs376007522    1  10209     1  10109   
rs368469931    3  30247     1  10139
Run Code Online (Sandbox Code Playgroud)

只有当df1 [['chr','pos']]时,我需要用df2 [['ID','OCHR','OSTOP']]更新df1中的''snp','chr','pos']匹配df2 [['OCHR','OSTOP']]

所以在这种情况下,更新后,df1看起来像:

chr       snp  x     pos a1 a2    
1  rs376643643  0  10040  G  A    
1  rs373328635  0  10066  C  G    
1  rs62651026   0  10208  C  G    
1  rs376007522  0  10209  C  G    
3  rs368469931  0  30247  C  T
Run Code Online (Sandbox Code Playgroud)

我使用merge作为解决方法:

df1 = pd.merge(df1, df2, how='left', left_on=["chr", "pos"], right_on=["OCHR", "OSTOP"],
                                     left_index=False, right_index=False, sort=False)
Run Code Online (Sandbox Code Playgroud)

然后

df1.loc[~df1.OCHR.isnull(), ["snp", "chr", "pos"]] = df1.loc[~df1.OCHR.isnull(), ["ID", "CHR", "STOP"]].values
Run Code Online (Sandbox Code Playgroud)

然后删除多余的列.

是的,它有效,但通过比较两个数据帧的值,直接做到这一点是什么方法,我只是不知道如何制定它,我无法在任何地方找到答案; 我想对此进行一般性回答可能会有所帮助.

我尝试过,但它不起作用:

df1.loc[(df1.chr==df2.OCHR) & (df1.pos==df2.OSTOP),["snp", "chr", "pos"]] = df2.loc[df2[['OCHR', 'OSTOP']] == df1.loc[(df1.chr==df2.OCHR) & (df1.pos==df2.OSTOP),["chr", "pos"]],['ID', ''CHR', 'STOP']].values
Run Code Online (Sandbox Code Playgroud)

谢谢,

斯特凡

Jia*_* Li 7

您可以使用该update功能(需要设置匹配条件以进行索引).我修改了您的示例数据以允许一些不匹配.

# your data
# =====================
# df1 pos is modified from 10020 to 10010
print(df1)

   chr      snp  x    pos a1 a2
0    1  1-10020  0  10010  G  A
1    1  1-10056  0  10056  C  G
2    1  1-10108  0  10108  C  G
3    1  1-10109  0  10109  C  G
4    1  1-10139  0  10139  C  T

print(df2)

            ID  CHR   STOP  OCHR  OSTOP
0  rs376643643    1  10040     1  10020
1  rs373328635    1  10066     1  10056
2   rs62651026    1  10208     1  10108
3  rs376007522    1  10209     1  10109
4  rs368469931    3  30247     1  10139

# processing
# ==========================
# set matching columns to multi-level index
x1 = df1.set_index(['chr', 'pos'])['snp']
x2 = df2.set_index(['OCHR', 'OSTOP'])['ID']
# call update function, this is inplace
x1.update(x2)
# replace the values in original df1
df1['snp'] = x1.values
print(df1)

   chr          snp  x    pos a1 a2
0    1      1-10020  0  10010  G  A
1    1  rs373328635  0  10056  C  G
2    1   rs62651026  0  10108  C  G
3    1  rs376007522  0  10109  C  G
4    1  rs368469931  0  10139  C  T
Run Code Online (Sandbox Code Playgroud)