2016-06-20 2 views
1

각 파일을 하나의 파일 (한 줄에 1 개씩)로 이동하고 두 번째 파일에서 해당 행의 한 열을 기준으로 모든 일치하는 기능을 찾으려고합니다. 나는 작은 파일에서 원하는 것을 수행하는이 솔루션을 가지고 있지만 대용량 파일에서는 매우 느립니다 (내 파일은 20,000,000 개가 넘습니다). Here's a sample of the two input files.두 배열 (파이썬)에서 일치하는 기능을 빠르게 찾을 수 있습니까?

내 (느린) 코드 : 당신이 conservationFile의 모든 걸쳐 루핑과

FEATUREFILE = 'S2_STARRseq_rep1_vsControl_peaks.bed' 
CONSERVATIONFILEDIR = './conservation/' 
with open(str(FEATUREFILE),'r') as peakFile, open('featureConservation.td',"w+") as outfile: 
for line in peakFile.readlines(): 
    chrom = line.split('\t')[0] 
    startPos = int(line.split('\t')[1]) 
    endPos = int(line.split('\t')[2]) 
    peakName = line.split('\t')[3] 
    enrichVal = float(line.split('\t')[4]) 

    #Reject negative peak starts, if they exist (sometimes this can happen w/ MACS) 
    if startPos > 0: 
     with open(str(CONSERVATIONFILEDIR) + str(chrom)+'.bed','r') as conservationFile: 
      cumulConserv = 0. 
      n = 0 
      for conservLine in conservationFile.readlines(): 
       position = int(conservLine.split('\t')[1]) 
       conservScore = float(conservLine.split('\t')[3]) 
       if position >= startPos and position <= endPos: 
        cumulConserv += conservScore 
        n+=1 
     featureConservation = cumulConserv/(n) 
     outfile.write(str(chrom) + '\t' + str(startPos) + '\t' + str(endPos) + '\t' + str(peakName) + '\t' + str(enrichVal) + '\t' + str(featureConservation) + '\n') 
+1

, 당신은 위치에 의해'conservationFile' 정렬 고려'peakFile'은 가정 오히려 N에 N^2이의 복잡성을 줄일 수있는이 방법이 정렬되었습니다. (당신은'sort -r -k2'를 사용할 수 있습니다) – Oren

+3

판다를 사용하십시오. 그것은 당신의 삶을 바꿀 수도 있습니다. – Chris

+0

@Chris OP가 도서관 추천을 찾지 못했습니다. –

답변

1

가장 좋은 해결책은 재 작성 것으로 보인다 판다에 대한 위의 코드. 다음은 몇 가지 매우 큰 파일에 나를 위해 잘 작동하고있는 작업은 다음과 같습니다

from __future__ import division 
import pandas as pd 

FEATUREFILE = 'S2_STARRseq_rep1_vsControl_peaks.bed' 
CONSERVATIONFILEDIR = './conservation/' 

peakDF = pd.read_csv(str(FEATUREFILE), sep = '\t', header=None, names=['chrom','start','end','name','enrichmentVal']) 
#Reject negative peak starts, if they exist (sometimes this can happen w/ MACS) 
peakDF.drop(peakDF[peakDF.start <= 0].index, inplace=True) 
peakDF.reset_index(inplace=True) 
peakDF.drop('index', axis=1, inplace=True) 
peakDF['conservation'] = 1.0 #placeholder 

chromNames = peakDF.chrom.unique() 

for chromosome in chromNames: 
    chromSubset = peakDF[peakDF.chrom == str(chromosome)] 
    chromDF = pd.read_csv(str(CONSERVATIONFILEDIR) + str(chromosome)+'.bed', sep='\t', header=None, names=['chrom','start','end','conserveScore']) 

for i in xrange(0,len(chromSubset.index)): 
    x = chromDF[chromDF.start >= chromSubset['start'][chromSubset.index[i]]] 
    featureSubset = x[x.start < chromSubset['end'][chromSubset.index[i]]] 
    x=None 
    featureConservation = float(sum(featureSubset.conserveScore)/(chromSubset['end'][chromSubset.index[i]]-chromSubset['start'][chromSubset.index[i]])) 
    peakDF.set_value(chromSubset.index[i],'conservation',featureConservation) 
    featureSubset=None 

peakDF.to_csv("featureConservation.td", sep = '\t') 
+0

좋은. 이 일이 잘된다면 :) – Vince

0

당신이 peakFile에서 한 줄을 읽을 때마다 그래서 if 문에 n+=1break을 고수하고 정상적으로 시작하려면 다소 도움이된다. 그 중 하나만 일치한다고 가정합니다.

또 다른 옵션은 버퍼링에 도움이 될 수있는 mmap를 사용하려고하는 것입니다

+0

아, 두 개 이상의 경기가 있습니다. peakFile에는 해당 지형지 물을 구성하는 위치 범위에 대한 정보가 있습니다 (즉, 피크 1은 위치 1-200 임). conservationFile에는 각 개별 위치에 대한 점수가 있으므로 peakFile 기능의 범위 내에있는 conservationFile 항목을 모두 찾아야합니다. – Ethan

+1

좋아, 내 잘못이야. 그러나 @Chris가 심각하게 [Pandas] (http://pandas.pydata.org/)에서 당신의 인생을 바꿀 수도 있다고 말했다. –

0

Bedtools 구체적으로 intersect 기능이 위해 만들어진 : 내 목적을 위해

http://bedtools.readthedocs.io/en/latest/content/tools/intersect.html

+0

bedtools를 시도했을 때 추가 열의 추가 데이터를 보존하는 데 문제가있었습니다. – Ethan

+0

밑줄 ('_')과 같은 구분 기호로 병합 한 다음 예를 들어 나눈 것입니다. 'perl -p -e "s/_/\ t/g;"'. 나는 bedtools가 BED가 아닌 데이터에 적합하지 않음을 인정합니다. 그러나 성능면에서 매우 유리하고 많은 명령과 옵션을 가지고 있기 때문에 이점은 단점을 가중시킵니다. 여분의 열을 나눌 수 있으며 나중에 출력 결과에 따라'awk' 또는'paste'를 사용하여 다시 추가 할 수 있습니다. 나는 이것에 기꺼이 도와 준다. – Vince

관련 문제