2013-05-22 115 views
1

我有一個包含數百萬行數據的大文本文件。第一列包含位置座標。我需要從這個原始數據創建另一個文件,但只包含基於位置座標的指定的非連續區間。我有另一個文件包含每個間隔的座標。例如,我的原始文件的格式與此類似:從python的大文本文件中有效地讀取部分

Position Data1 Data2 Data3 Data4 
55   a  b  c  d 
63   a  b  c  d 
68   a  b  c  d 
73   a  b  c  d 
75   a  b  c  d 
82   a  b  c  d 
86   a  b  c  d 

然後讓說我有一個包含間隔我的文件看起來是這樣的......

name1 50 72 
name2 78 93 

然後我想我的新文件看起來像這樣...

Position Data1 Data2 Data3 Data4 
55   a  b  c  d 
63   a  b  c  d 
68   a  b  c  d 
82   a  b  c  d 
86   a  b  c  d 

到目前爲止,我已經創建了一個函數從包含在特定的時間間隔,以我的新文件中的原始文件寫入數據。我的代碼如下:

def get_block(beg,end): 
    output=open(output_table,'a') 
    with open(input_table,'r') as f: 
     for line in f: 
     line=line.strip("\r\n") 
     line=line.split("\t") 
     position=int(line[0]) 
     if int(position)<=beg: 
      pass 
     elif int(position)>=end: 
      break 
     else: 
      for i in line: 
       output.write(("%s\t")%(i)) 
      output.write("\n") 

我然後創建一個使用類似這樣的上述功能包含我的間隔通過我的原始文件對,然後循環列表:

#coords=[[start1,stop1],[start2,stop2],[start3,stop3]..etc] 
for i in coords: 
    start_p=int(i[0]) ; stop_p=int(i[1]) 
    get_block(start_p,stop_p) 

這將執行我想要什麼但是當它沿着我的座標列表移動時,它會呈指數級變慢,因爲我不得不通讀整個文件,直到每次通過循環都達到指定的起始座標。有沒有更有效的方法來完成這個?有沒有辦法每次跳到一個特定的行,而不是閱讀每一行?

+0

你是什麼意思?它運行,只是非常緩慢,這是我的代碼。 – abovezero

+0

感謝您收到錯誤信息,我必須添加一個額外的\錯誤。它現在已經修復。 – abovezero

+0

'pandas'可能值得研究 – dm03514

回答

0

感謝您使用pandas的建議。以前,我原來的代碼已經運行了大約18個小時,只完成了一半。使用pandas,它在5分鐘內創建了我想要的文件。爲了將來的參考,如果其他人有類似的任務,這裏是我使用的代碼。

import pandas as pd 

data=pd.io.parsers.read_csv(input_table,delimiter="\t") 
for i in coords: 
    start_p=int(i[0]);stop_p=int(i[1]) 
    df=data[((data.POSITION>=start_p)&(data.POSITION<=stop_p))] 
    df.to_csv(output_table,index=False,sep="\t",header=False,cols=None,mode='a') 
0

我只是使用內置的csv模塊來簡化讀取輸入。爲了進一步加快速度,可以一次讀入所有的座標範圍,這將允許選擇過程一次通過數據文件。

import csv 

# read all coord ranges into memory 
with open('ranges', 'rb') as ranges: 
    range_reader = csv.reader(ranges, delimiter='\t') 
    coords = [map(int, (start, stop)) for name,start,stop in range_reader] 

# make one pass through input file and extract positions specified 
with open('output_table', 'w') as outf, open('input_table', 'rb') as inf: 
    input_reader = csv.reader(inf, delimiter='\t') 
    outf.write('\t'.join(input_reader.next())+'\n') # copy header row 
    for row in input_reader: 
     for coord in coords: 
      if coord[0] <= int(row[0]) <= coord[1]: 
       outf.write('\t'.join(row)+'\n') 
       break; 
相關問題