【问题标题】:How to merge two pandas dataframes (or transfer values) by comparing ranges of values如何通过比较值的范围来合并两个熊猫数据框(或传输值)
【发布时间】:2017-09-14 11:33:15
【问题描述】:

在以下数据中:

data01 =

contig  start    end    haplotype_block 
2   5207    5867    1856
2   155667    155670    2816
2   67910    68022  2
2   68464    68483  3
2   525    775  132
2   118938    119559    1157

data02 =

contig    start   last    feature gene_id gene_name   transcript_id
2   5262    5496    exon    scaffold_200003.1   CP5 scaffold_200003.1
2   5579    5750    exon    scaffold_200003.1   CP5 scaffold_200003.1
2   5856    6032    exon    scaffold_200003.1   CP5 scaffold_200003.1
2   6115    6198    exon    scaffold_200003.1   CP5 scaffold_200003.1
2   916 1201    exon    scaffold_200001.1   NA  scaffold_200001.1
2   614 789 exon    scaffold_200001.1   NA  scaffold_200001.1
2   171 435 exon    scaffold_200001.1   NA  scaffold_200001.1
2   2677    2806    exon    scaffold_200002.1   NA  scaffold_200002.1
2   2899    3125    exon    scaffold_200002.1   NA  scaffold_200002.1

问题:

  • 我想比较这两个数据帧的范围(开始 - 结束)。
  • 如果范围重叠,我想将 gene_idgene_name 值从 data02 传输到 data01 中的新列。

我试过(使用熊猫):

data01['gene_id'] = ""
data01['gene_name'] = ""

data01['gene_id'] = data01['gene_id'].\
apply(lambda x: data02['gene_id']\
        if range(data01['start'], data01['end'])\
           <= range(data02['start'], data02['last']) else 'NA')

如何改进此代码?我目前坚持使用熊猫,但如果使用字典更好地解决问题,我愿意接受。但是,请解释一下这个过程,我愿意学习而不是仅仅得到答案。

谢谢,

期望的输出:

contig  start    end    haplotype_block    gene_id    gene_name
2   5207    5867    1856    scaffold_200003.1,scaffold_200003.1,scaffold_200003.1   CP5,CP5,CP5

# the gene_id and gene_name are repeated 3 times because three intervals (i.e 5262-5496, 5579-5750, 5856-6032) from data02 overlap(or touch) the interval ranges from data01 (5207-5867)

# So, whenever there is overlap of the ranges between two dataframe, copy the gene_id and gene_name.

# and simply NA on gene_id and gene_name for non overlapping ranges

2   155667    155670    2816    NA    NA
2   67910    68022  2    NA    NA
2   68464    68483  3    NA    NA
2   525    775  132    scaffold_200001.1   NA
2   118938    119559    1157    NA    NA

【问题讨论】:

  • 我对目标是什么感到困惑。如果你能拼出你的输出是什么样子的,我很乐意再看看。
  • @piRSquared:刚刚添加了所需的输出。我希望这是有道理的。解决这个问题的更好方法是首先在两个数据帧上通过 conting 和 start 对数据进行排序(以防止大量的 for 循环),我已经这样做了;但不在上面的data01和data02中。

标签: python pandas dataframe merge bioinformatics


【解决方案1】:

我知道您使用的是 python,但您的问题可以使用经典的生物信息学工具 bedtools intersect: http://bedtools.readthedocs.io/en/latest/content/tools/intersect.html 轻松解决

您的两个输入文件都遵循标准 BED 格式:http://bedtools.readthedocs.io/en/latest/content/general-usage.html

Bedtools intersect 为您提供了有关如何确定两个区域之间的交叉点或重叠的高级逻辑。我相信它也可以直接对 bgzipped 输入进行操作。

【讨论】:

  • 我以前用过床具。由于start - end 值,我的数据采用床格式,但我不确定是否可以工作并且能够传输这些值(完全按照我的意愿)。我一直在使用 python、pandas、list、dict 一段时间,使用这些工具来完成特定任务感觉更好。标准的生物信息学工具很好(如 bwa、vcf 文件等),但如果过于具体,工具就会变得烦人而不是有用。
  • 我刚刚重温了床上用品。因为,我的目的是最好使用 python 和 pandas(其他字典)。我正在做的事情是大管道的一部分,引入床具只会让事情变得比简单更复杂。不过,您可能有其他想法/意见。如果有的话,我将不胜感激。谢谢
  • Bedtools 旨在解决您的问题 - 这是生物信息学中的常见问题。算法本身可能有些细微差别,特别是如果您希望它高效。我建议您在开始重新实现算法之前尝试一下。 ;)
  • 唯一对我有帮助的方法是 bedtools intersect 这将使我失去 data01 或 bedtools merge 中的数据,但我只想更新 data01 中的列值而不是合并所有信息。我不知道。我将花一些时间在bedtools 上,否则如果它不起作用,我在 python 领域太舒服了。大声笑。
  • 我不会担心来自bedtools merge 的额外列。床具将非常快。您可以将结果加载到 pandas 中并向下选择感兴趣的列。
【解决方案2】:

您应该在 python 中使用区间树函数,它们非常高效且内存友好,我尝试了类似的方法运行它来解决后来解决的一些问题,但这是我编写的代码, Using Interval tree to find overlapping regions

您可以在此代码的基础上进行构建。

【讨论】:

  • 谢谢,我会调查的。
【解决方案3】:
s1 = data01.start.values
e1 = data01.end.values
s2 = data02.start.values
e2 = data02['last'].values

overlap = (
    (s1[:, None] <= s2) & (e1[:, None] >= s2)
) | (
    (s1[:, None] <= e2) & (e1[:, None] >= e2)
)

g = data02.gene_id.values
n = data02.gene_name.values

i, j = np.where(overlap)
idx_map = {i_: data01.index[i_] for i_ in pd.unique(i)}

def make_series(m):
    s = pd.Series(m[j]).fillna('').groupby(i).agg(','.join)
    return s.rename_axis(idx_map).replace('', np.nan)

data01.assign(
    gene_id=make_series(g),
    gene_name=make_series(n),
)

【讨论】:

    【解决方案4】:

    如果您想要比床具快得多的东西和/或 Python 科学堆栈的本地居民,请尝试 pyranges

    import pyranges as pr
    
    c1 = """Chromosome  Start    End    haplotype_block
    2   5207    5867    1856
    2   155667    155670    2816
    2   67910    68022  2
    2   68464    68483  3
    2   525    775  132
    2   118938    119559    1157"""
    
    c2 = """Chromosome Start End  feature gene_id gene_name   transcript_id
    2   5262    5496    exon    scaffold_200003.1   CP5 scaffold_200003.1
    2   5579    5750    exon    scaffold_200003.1   CP5 scaffold_200003.1
    2   5856    6032    exon    scaffold_200003.1   CP5 scaffold_200003.1
    2   6115    6198    exon    scaffold_200003.1   CP5 scaffold_200003.1
    2   916 1201    exon    scaffold_200001.1   NA  scaffold_200001.1
    2   614 789 exon    scaffold_200001.1   NA  scaffold_200001.1
    2   171 435 exon    scaffold_200001.1   NA  scaffold_200001.1
    2   2677    2806    exon    scaffold_200002.1   NA  scaffold_200002.1
    2   2899    3125    exon    scaffold_200002.1   NA  scaffold_200002.1"""
    
    gr1, gr2 = pr.from_string(c1), pr.from_string(c2)
    
    j = gr1.join(gr2).sort()
    
    print(j)
    # +--------------+-----------+-----------+-------------------+-----------+-----------+------------+-------------------+-------------+-------------------+
    # |   Chromosome |     Start |       End |   haplotype_block |   Start_b |     End_b | feature    | gene_id           | gene_name   | transcript_id     |
    # |   (category) |   (int32) |   (int32) |           (int64) |   (int32) |   (int32) | (object)   | (object)          | (object)    | (object)          |
    # |--------------+-----------+-----------+-------------------+-----------+-----------+------------+-------------------+-------------+-------------------|
    # |            2 |       525 |       775 |               132 |       614 |       789 | exon       | scaffold_200001.1 | nan         | scaffold_200001.1 |
    # |            2 |      5207 |      5867 |              1856 |      5262 |      5496 | exon       | scaffold_200003.1 | CP5         | scaffold_200003.1 |
    # |            2 |      5207 |      5867 |              1856 |      5579 |      5750 | exon       | scaffold_200003.1 | CP5         | scaffold_200003.1 |
    # |            2 |      5207 |      5867 |              1856 |      5856 |      6032 | exon       | scaffold_200003.1 | CP5         | scaffold_200003.1 |
    # +--------------+-----------+-----------+-------------------+-----------+-----------+------------+-------------------+-------------+-------------------+
    # Unstranded PyRanges object has 4 rows and 10 columns from 1 chromosomes.
    # For printing, the PyRanges was sorted on Chromosome.
    
    print(j.df)
    #   Chromosome  Start   End  haplotype_block  Start_b  End_b feature            gene_id gene_name      transcript_id
    # 0          2    525   775              132      614    789    exon  scaffold_200001.1       NaN  scaffold_200001.1
    # 1          2   5207  5867             1856     5262   5496    exon  scaffold_200003.1       CP5  scaffold_200003.1
    # 2          2   5207  5867             1856     5579   5750    exon  scaffold_200003.1       CP5  scaffold_200003.1
    # 3          2   5207  5867             1856     5856   6032    exon  scaffold_200003.1       CP5  scaffold_200003.1
    

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      • 2014-10-30
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多