【问题标题】:reading sections from a large text file in python efficiently有效地从python中的大型文本文件中读取部分
【发布时间】:2013-05-22 14:42:57
【问题描述】:

我有一个包含数百万行数据的大型文本文件。第一列包含位置坐标。我需要从这个原始数据创建另一个文件,但它只包含基于位置坐标的指定非连续间隔。我有另一个文件包含每个间隔的坐标。例如,我的原始文件格式类似于:

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)

这执行了我想要的操作,但是当它沿着我的坐标列表移动时它会以指数方式变慢,因为我必须通读整个文件,直到每次通过循环到达指定的起始坐标。有没有更有效的方法来实现这一点?有没有办法每次都跳到特定的行而不是阅读每一行?

【问题讨论】:

  • 什么意思?它运行,只是很慢,这是我的代码。
  • 感谢您发现错误,我一定是错误地添加了额外的 \。现在已修复。
  • pandas 可能值得研究
  • 尝试预加载范围,然后对文件进行一次迭代。在这种情况下,如果您有 100 个不同的范围,您将打开文件并从中读取 100 次。而是将范围加载到内存中,对大文件进行 1 次迭代,然后对范围进行多次迭代。
  • 你可以试试pandas。您可以将整个文件读入 pandas.DataFrame 并像数组一样轻松地对其进行切片。

标签: python split concatenation large-files sections


【解决方案1】:

感谢使用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')

【讨论】:

    【解决方案2】:

    我只是使用内置的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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      • 2016-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多