【发布时间】:2015-10-23 10:21:21
【问题描述】:
我搜索了很多答案,最接近的问题是Compare 2 columns of 2 different pandas dataframes, if the same insert 1 into the other in 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
请注意,“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
只有当 df1[['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
我已使用合并作为解决方法:
df1 = pd.merge(df1, df2, how='left', left_on=["chr", "pos"], right_on=["OCHR", "OSTOP"],
left_index=False, right_index=False, sort=False)
然后
df1.loc[~df1.OCHR.isnull(), ["snp", "chr", "pos"]] = df1.loc[~df1.OCHR.isnull(), ["ID", "CHR", "STOP"]].values
然后删除多余的列。
是的,它有效,但是通过比较两个数据框的值来直接做到这一点的方法是什么,我只是不知道如何制定它,而且我在任何地方都找不到答案;我想这可能会很有用。
我试过了,但它不起作用:
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
谢谢,
斯蒂芬
【问题讨论】:
-
"我只需要在 df1[[ 'chr', 'pos']] 匹配 df2[['OCHR', 'OSTOP']]" 这不是说只有在
char和pos在df1 在 df2 中匹配OCHR和OSTOP? -
如果合并 chr,ochr 和 pos,ostop,那么就不需要更新了。也许你的意思是更新 chr->CHR 和 post->STOP ?
-
这就是您的示例中的情况,合并后,您想要更新 df1.chr -> df2.CHR 和 df1.pos -> df2.STOP,如果是错字,可能会更正
-
这可以在 SQL 更新连接查询的一行中完成。如果您的 dfs 来自数据库,请考虑 SQL 关系引擎的强大功能。
-
@Alexander,不完全是,当 df1 中的 chr 和 pos 与 df2 中的 OCHR 和 OSTOP 匹配时,所有三列(snp、chr 和 pos)都需要更新。