【问题标题】:Merging pandas dataframes on multiple conditions (python/pandas)在多个条件下合并 pandas 数据帧(python/pandas)
【发布时间】:2016-01-19 22:00:51
【问题描述】:

我有一个由 ID、Chr 和位置组成的 Python/Pandas 数据框 (df1)。和一个由相同类型的数据(ID、Chr、Position)df2组成的数据框。

我想获得第三个数据帧 (df3),它仅根据 df1 和 df2 之间的 Chr 列保留 df1 的行,以及位于 pos-start 和df2 的后端;此外,它需要添加匹配起源的 df2 的 ID 或行。

我发现这非常困难,有人有想法吗?

请看下面的例子:

df1

ID1 Chr pos
a   12  500
b   12  250
c   12  300
d   16  2000
e   16  1050
f   16  1075
d   16  1150
g   17  8000
h   17  550
i   17  500

df2

ID2 Chr pos-start   pos-end
x   12  200      400
y   16  1000    1100
z   16  1070    1200

结果 df3

ID2 ID1 Chr Pos
x   b   12  250
x   c   12  300
y   e   16  1050
y   f   16  1000
z   f   16  1075
z   d   16  1150

【问题讨论】:

    标签: python pandas merge dataframe data-manipulation


    【解决方案1】:

    一种方法是进行普通的旧合并,然后丢弃超出范围的值:

    In [11]: df3 = df1.merge(df2)
    
    In [12]: df3
    Out[12]:
       ID1  Chr   pos ID2  pos-start  pos-end
    0    a   12   500   x        200      400
    1    b   12   250   x        200      400
    2    c   12   300   x        200      400
    3    d   16  2000   y       1000     1100
    4    d   16  2000   z       1070     1200
    5    e   16  1050   y       1000     1100
    6    e   16  1050   z       1070     1200
    7    f   16  1075   y       1000     1100
    8    f   16  1075   z       1070     1200
    9    d   16  1150   y       1000     1100
    10   d   16  1150   z       1070     1200
    
    In [13]: df3[(df3["pos-start"] < df3["pos"]) & (df3["pos"] < df3["pos-end"])]
    Out[13]:
       ID1  Chr   pos ID2  pos-start  pos-end
    1    b   12   250   x        200      400
    2    c   12   300   x        200      400
    5    e   16  1050   y       1000     1100
    7    f   16  1075   y       1000     1100
    8    f   16  1075   z       1070     1200
    10   d   16  1150   z       1070     1200
    

    并丢弃不需要的列:

    In [14]: df3[(df3["pos-start"] < df3["pos"]) & (df3["pos"] < df3["pos-end"])][['ID2', 'ID1', 'Chr', 'pos']]
    Out[14]:
       ID2 ID1  Chr   pos
    1    x   b   12   250
    2    x   c   12   300
    5    y   e   16  1050
    7    y   f   16  1075
    8    z   f   16  1075
    10   z   d   16  1150
    

    【讨论】:

    • 先过滤后合并不是更高效吗?
    • @Alexander 肯定会的。我认为存在基于 loc 的解决方案。
    • @Alexander 实际上我不太确定。如果您(或任何人)得到它,将投票赞成。我以为您可以以某种方式使用 IndexSlice,但不再相信 :(
    • 我同意你的看法。我找不到比您在上面发布的更优雅的解决方案。当然,我总是可以扩展它... (-;
    • @Alexander :)。我有点惊讶df2.set_index(['Chr', 'ID2']).loc[pd.IndexSlice[df1["Chr"],:], ["pos-start", "pos-end"]] 没有像我预期的那样工作......
    猜你喜欢
    • 2017-12-30
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2019-08-10
    相关资源
    最近更新 更多