2013-05-22 43 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; 
相关问题