我怎么知道某个位置是否在使用python的区域中

时间:2017-04-05 04:09:23

标签: python

我有2个文件。

文件A有3列:染色体,起始位置,结束位置。

CHR,START,END
chr1,1203245,1203374
chr1,1202020,1202213
chr1,1201293,1201465
chr1,1200844,1201128
chr1,1200527,1200585

文件B有2列:染色体,位置。

CHR,POS
chr1,1579264
chr1,1641372
chr1,3020521
chr2,2097836
chr3,2374462       

两个文件都很大。

如何使用python判断文件B的每个位置是否在文件A的任何区域?如果只有一个位置和一个区域,我可以编写代码,但我不知道区域列表的线索。

Position is in a region表示CHR应该相同且POS >= START and POS <= END,例如,文件B的chr1,1203250应位于文件A的chr1,1203245,1203374

我接受奥斯卡布伦的建议并编写代码:

for i,r in B.iterrows():
    B.loc[i, 'in_A'] = any((r.CHR == A.CHR) & (r.POS >= A.SATRT) & (r.POS <= A.END))

但是两个文件都很大,代码仍在运行。如果有办法让这个更快?

2 个答案:

答案 0 :(得分:0)

  1. 如果您的文件很大,那么无法只在数据框中加载它们,因为它会填满整个内存。

  2. 比较B的位置与A中的每个区间,因为这非常低效(理解:非常慢)。

  3. 相反,这样做:

    1. 按chrom,start,end对文件进行排序。

    2. 同时迭代两个文件的行。这样的事情(对于这个想法;它不考虑染色体,并且可能有错误,加上你需要定义保存位置的方式):

      a = open("A")
      b = open("B")
      # init
      (chromA,start,end) = a.readline().split(",")
      (chromB,pos) = b.readline().split(",")
      while 1:
          try:
              if pos < start:
                  # Read more lines from B
                  (chromB,pos) = b.readline().split(",")
              elif pos > end:
                  # Read more lines from A
                  (chromA,start,end) = a.readline().split(",")
              else:
                  # Pos is in the [start, end] interval
                  # Save the result and go to the next pos
                  savePos()  
                  (chromB,pos) = b.readline().split(",")
          except StopIteration:
              break
      
    3. 我真正的建议是不要像过去的每个生物信息学家那样手动完成,而是使用“bedtools”或像BioPython这样的现有Python库。重新发明轮子是研究时间和资源的可怕损失。

答案 1 :(得分:-1)

我已将您的问题解释为&#39;是A的所有行中任何START和END值之间B的每一行中的POS值。如果这是正确的,使用pandas数据分析库可以使用这样的东西:

import pandas as pd

A = pd.read_csv('path/to/A.csv')
B = pd.read_csv('path/to/B.csv')

for i, r in B.iterrows():
    B.loc[i, 'in_A'] = any((r.POS > A.START) & (r.POS < A.END))

print(B)

>>     CHR      POS   in_A
    0  chr1  1579264  False
    1  chr1  1641372  False
    2  chr1  3020521  False
    3  chr2  2097836  False
    4  chr3  2374462  False

这遍历B中的每一行,并生成一个TRUE的布尔数组,其中(POS&gt; START)&amp; (POS&lt; END)对于A的所有行。然后在B数据帧中创建一个新列,如果POS存在于A的START / END限制的任何中,则为True。

有意义吗?