【问题标题】:Merge 2 dataframe depending on column values根据列值合并 2 个数据框
【发布时间】:2020-09-04 14:34:25
【问题描述】:

您好,我有一个数据框,例如:

Df1

Groups   Names                          COLs  COLe
G1     ABC_DEF.1:2-300():Canis_lupus    2     300
G1     SEQUENCE1                        NA    NA
G1     SEQUENCE2                        NA    NA
G1     SEQUENCE3                        NA    NA
G1     ABC_DEF.1:400-600():Canis_lupus  400   600
G1     IJK_LMN.1:20-200():Bos_taurus    20    200
G2     OP_D:500-1000():Felis_catus      500   1000
G2     Sequence3                        NA    NA

和另一个df,例如:

df2

COL1       COL2       COL3 COL4 COL5 COL6 Species
ABC_DEF.1  SEQUENCE1  20   80   A    1    Canis_lupus
ABC_DEF.1  SEQUENCE2  500  548  C    3    Canis_lupus
QKC_DEF.2  SEQUENCE2  500  548  Z    O    Canis_lupus
ABC_DEF.1  SEQUENCE4  520  800  T    9    Canis_lupus
IJK_LMN.1  SEQUENCE1  10   18   D    4    Bos_taurus
AQK_LM9.1  SEQUENCE1  10   18   P    5    Bos_taurus
IJK_LMN.1  SEQUENCE1  30   50   U    0    Bos_taurus
IJK_LMN.1  SEQUENCE3  30   176  E    5    Bos_taurus
OP_D       SEQUENCE3  600  700  F    6    Felis_catus
OP_D       SEQUENCE1  539  878  G    7    Felis_catus
OP_S       SEQUENCE4  20   78   H    8    Felis_catus

这个想法是创建一个新的df,它将在所有数据帧之间合并

这是预期的结果

Groups Names                            COL2        COL3 COL4 COL5 COL6
G1     ABC_DEF.1:2-300():Canis_lupus   SEQUENCE1   20   80   A    1
G1     ABC_DEF.1:400-600():Canis_lupus SEQUENCE2   500  548  B    2
G1     IJK_LMN.1:20-200():Bos_taurus   SEQUENCE1   30   50   U    0
G1     IJK_LMN.1:20-200():Bos_taurus   SEQUENCE3   30   176  E    5
G2     OP_D:500-1000():Felis_catus     SEQUENCE3   600  700  F    6

这个想法是解析Df1中的每个Groups 我们以G1 为例:

ABC_DEF.1:2-300():Canis_lupusdf2 中,

如果我有与Names 中存在的元素相对应的COL2,我会查看df

我有 SEQUENCE1SEQUENCE2 属于同一组:

那么如果COL3COL4COLs - Cole 之间(这里是2-300),

所以 SEQUENCE120-80 然后我将该行添加到新的 df 中:

Groups Names                            COL2        COL3 COL4 COL5 COL6
G1     ABC_DEF.1:2-300():Canis_lupus   SEQUENCE1   20   80   A    1

SEQUENCE2500-548 所以它在2-300之上

然后我对G1 中的第二个名字感兴趣:ABC_DEF.1:400-600():Canis_lupus

还有SEQUENCE1SEQUENCE2 但这里只有SEQUENCE2400-600 范围内所以我只添加这个

Groups Names                            COL2        COL3 COL4 COL5 COL6
G1     ABC_DEF.1:2-300():Canis_lupus   SEQUENCE1   20   80   A    1
G1     ABC_DEF.1:400-600():Canis_lupus SEQUENCE2   500  548  B    2

现在IJK_LMN.1:20-200():Bos_taurus,我到了df2

SEQUENCE1对应并在20-200范围内

Groups Names                            COL2        COL3 COL4 COL5 COL6
G1     ABC_DEF.1:2-300():Canis_lupus   SEQUENCE1   20   80   A    1
G1     ABC_DEF.1:400-600():Canis_lupus SEQUENCE2   500  548  B    2
G1     IJK_LMN.1:20-200():Bos_taurus   SEQUENCE1   30   50   U    0

有人对 pandas 和 python 有想法吗?

我想我们应该使用合并和拆分名称来获得每个部分:

例如:

ABC_DEF.1:2-300():Canis_lupus 

必须拆分为:

  1. ABC_DEF.1(第一个 : 之前的所有内容)
  2. Canis_lupus(最后一个 : 之后的部分)

【问题讨论】:

  • 如果您尝试使用pandas.merge?您可以将每个数据框中的多列指定为键
  • 你好@PaulH,是的,我知道你如何使用 pd.merge 但我真的不知道如何处理这个范围问题
  • 听起来你最好的选择是对一些列进行更一般的合并,并根据你的值范围相关标准过滤结果。将您已经尝试过的东西作为出发点会很好

标签: python regex pandas split


【解决方案1】:

首先,您应该考虑采取以下步骤:

1 - 从df1 中删除仅包含 SEQUENCE1、SEQUENCE2 等的行。据我了解,它们不提供服务,因为没有范围和具体名称。 2-从列Names中删除第一个“:”之后的所有内容

然后,您可以执行以下操作:

3 - 使用 pandas.merge 合并两个数据框:

df_merged = pd.merge(df1,df2, how = 'inner', left_on = 'Name', right_on = 'COL1')

4 - 根据您在 COLsCOLe 之间陈述的关于 COL3COL4 的条件过滤掉生成的数据框。

当您像这样进行内部连接时,您将得到重复的结果,因为 COL1 具有多个 COL2 值(序列)。因此,您可以轻松地按您想要的条件过滤出正确的结果。

您可以在此处查看更多关于 SQL 与 pandas 的比较:

https://pandas.pydata.org/docs/getting_started/comparison/comparison_with_sql.html

如果我的回答有帮助,请告诉我。

【讨论】:

  • 好的,我成功进入第三部分了!现在我需要找到一种方法来删除每行的 Cols 和 Cole 范围内的 COL3 COL4,你有什么想法吗?
  • 好!试试这个:df_final = df_merged[(df_merged['COL3'] >= df_merged['COLs']) & (df_merged['COL4'] <= df_merged['COLe'])]。这样,您将只保留 COLs 和 COLe 值之间的值然后您可以使用 df.drop() 方法删除不需要的列。如果这个答案对您来说足够了,请将其标记为已接受的答案。 =)
猜你喜欢
  • 1970-01-01
  • 2023-01-13
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多