【问题标题】:How can I merge/join multiple columns from two dataframes, depending on a matching pattern如何根据匹配模式合并/连接来自两个数据帧的多个列
【发布时间】:2021-05-16 18:09:46
【问题描述】:

我想根据染色体列中的相似模式合并两个数据框。我对 R & BASH 进行了各种尝试,例如 "data.table" "tidyverse" 和 & merge()。有人可以通过在 R、BASH、Python、Perl 等中提供替代解决方案来帮助我解决这个解决方案吗?我想根据染色体信息合并并保留两个计数/RXN。

注意:这两个 DF 没有对齐,我也很好奇如果缺少某些值会发生什么。

感谢和欢呼:

DF1:

Chromosome;RXN;ID
1009250;q9hxn4;NA
1010820;p16256;NA
31783;p16588;"PNTOt4;PNTOt4pp"
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;"DHQTi;DQDH"

DF2:

Chromosome;Count1;Count2;Count3;Count4;Count5
203;1;31;1;0;0;0
1010820;152;7;0;11;4
1009250;5;0;0;17;0
31783;1;0;0;0;0;0

预期结果:

Chromosome;RXN;Count1;Count2;Count3;Count4;Count5
1009250;q9hxn4;5;0;0;17;0
1010820;p16256;152;7;0;11;4
31783;p16588;1;0;0;0;0
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;1;31;1;0;0;0

【问题讨论】:

  • 所以df1 中的Chromosome1 应该匹配df2 中的Chromosome2
  • Chromosome1 & Chromosome2 在您的示例中没有匹配项。你想只加入这两个表吗?
  • 您能否详细说明“相似的匹配模式”对您的用例意味着什么?这听起来很主观,而编程解决方案最适合客观定义。
  • 这里的预期结果似乎依赖于您提供的不同 DF2 数据,这将使我们无法测试任何潜在的解决方案。你能解决这个问题吗?
  • 感谢大家迄今为止的反馈。我调整了两个数据集并澄清了问题。我想匹配两个文件中的“染色体”列标题

标签: language-agnostic


【解决方案1】:

正如正文中提到的 bash,我为您提供了一个 awk 解决方案。数据框位于文件df1df2

$ awk '
BEGIN {
    FS=OFS=";"         # input and output field delimiters
}
NR==FNR {              # process df1
    a[$1]=$2           # hash to an array, 1st is the key, 2nd the value
    next               # process next record
}
{                      # process df2
    $2=(a[$1] OFS $2)  # prepend RXN field to 2nd field of df2
}1' df1 df2            # 1 is output command, mind the file order

最后两行可能写得更清楚:

...
{
    print $1,a[$1],$2,$3,$4,$5,$6
}' df1 df2

输出:

Chromosome;RXN;Count1;Count2;Count3;Count4;Count5
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;1;31;1;0;0;0
1010820;p16256;152;7;0;11;4
1009250;q9hxn4;5;0;0;17;0
31783;p16588;1;0;0;0;0;0

输出将按df2 的顺序排列。将不包括存在于df1 但不存在于df2 中的染色体。 df2 中但不在df1 中的染色体将从df2 输出,RXN 字段为空。此外,如果df1 中有重复的染色体,则使用最后一个。如果有问题,可以修复。

【讨论】:

  • 这个解决方案非常优雅和干净,感谢您提出这个解决方案。我花了几天时间尝试使用 AWK,但无法弄清楚。你真的是一个 BASH 向导:D
【解决方案2】:

如果我正确理解您的要求,这应该在 Python 中完成。我已将 Chromosome 列添加到每个 DataFrame 的索引中。

from io import StringIO

txt1 = '''Chromosome;RXN;ID
1009250;q9hxn4;NA
1010820;p16256;NA
31783;p16588;"PNTOt4;PNTOt4pp"
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;"DHQTi;DQDH"'''

txt2 = """Chromosome;Count1;Count2;Count3;Count4;Count5;Count6
203;1;31;1;0;0;0
1010820;152;7;0;11;4
1009250;5;0;0;17;0
31783;1;0;0;0;0;0"""

df1 = pd.read_csv(
    StringIO(txt1),
    sep=';',
    index_col=0,
    header=0
)

df2 = pd.read_csv(
    StringIO(txt2),
    sep=';',
    index_col=0,
    header=0
)
DF1:
                                         RXN               ID
Chromosome
1009250                               q9hxn4              NaN
1010820                               p16256              NaN
31783                                 p16588  PNTOt4;PNTOt4pp
203         3-DEHYDROQUINATE-DEHYDRATASE-RXN       DHQTi;DQDH

DF2:
            Count1  Count2  Count3  Count4  Count5  Count6
Chromosome
203              1      31       1       0       0     0.0
1010820        152       7       0      11       4     NaN
1009250          5       0       0      17       0     NaN
31783            1       0       0       0       0     0.0
result = pd.concat(
    [df1.sort_index(), df2.sort_index()],
    axis=1
)
print(result)
                                         RXN               ID  Count1  Count2  Count3  Count4  Count5  Count6
Chromosome
203         3-DEHYDROQUINATE-DEHYDRATASE-RXN       DHQTi;DQDH       1      31       1       0       0     0.0
31783                                 p16588  PNTOt4;PNTOt4pp       1       0       0       0       0     0.0
1009250                               q9hxn4              NaN       5       0       0      17       0     NaN
1010820                               p16256              NaN     152       7       0      11       4     NaN

concat 命令还通过简单地为列填充 NaN 值来处理不匹配的索引,例如df1 如果 df2 没有相同的索引,反之亦然。

【讨论】:

  • 嘿@Nick,这对我来说非常有用。您将“染色体”列设为每个 DF 的索引是什么意思?在这种情况下你是怎么做到的?我试过:df1.set_index('Chromosome',inplace=True) 但它没有提供我预期的结果。我仍然有两个带有“染色体”的独特列。再次感谢!
  • 谢谢。我现在添加了加载数据并将 Chromosome 列设置为索引的代码。我还添加了一列“Count6”,因为它似乎缺少与存在的列数相匹配。
  • 感谢您指定如何将列设置为索引但是,我使用的是两个大文件,而不是字符串。我继续遇到错误:raise InvalidIndexError( pandas.errors.InvalidIndexError: Reindexing only valid with uniquely valued Index objects 我认为问题是我在被索引的行中有重复项,但它并没有太大变化
  • df1 = pd.read_csv('DF1.csv', sep=';',index_col=0,header=0) print (df1) df1.index df2 = pd.read_csv ('DF1.csv', sep=';',index_col=0,header=0) print (df2) df2.index result = pd.concat( [df1.sort_index(), df2.sort_index()], axis=1) #Error arises here print(result) result.to_csv('test.csv', index=False)
  • 听起来有重复的染色体条目。我建议在这里查看答案之一:stackoverflow.com/questions/50242968/…
猜你喜欢
  • 2020-08-12
  • 2016-08-07
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多