【问题标题】:Python - reading huge filePython - 读取大文件
【发布时间】:2017-09-15 18:08:34
【问题描述】:

我有以下代码尝试处理包含多个 xml 元素的大文件。

from shutil import copyfile
files_with_companies_mentions=[]
# code that reads the file line by line
def read_the_file(file_to_read):
    list_of_files_to_keep=[]
    f = open('huge_file.nml','r')
    lines=f.readlines()
    print("2. I GET HERE ")
    len_lines = len(lines)
    for i in range(0,len(lines)):
        j=i
        if '<?xml version="1.0"' in lines[i]:
            next_line = lines[i+1]
            write_f = open('temp_files/myfile_'+str(i)+'.nml', 'w')
            write_f.write(lines[i])
            while '</doc>' not in next_line:
                write_f.write(next_line)
                j=j+1
                next_line = lines[j]
            write_f.write(next_line)    
            write_f.close()
            list_of_files_to_keep.append(write_f.name)
    return list_of_files_to_keep

该文件超过 700 MB,包含超过 2000 万行。有没有更好的处理方法?

如您所见,我需要使用诸如i 之类的指标变量来引用上一行和下一行。

我面临的问题是它非常慢。每个文件都需要 1 个多小时,而我有多个。

【问题讨论】:

  • 您面临的问题是什么?磁盘空间?
  • 速度很慢。我编辑了我的原始帖子。
  • 并行处理如何同时处理这些文件中的几个?
  • 您可以执行“for line in f:”,然后根据需要逐行逐行执行,而无需先将它们全部读入内存。您需要重新设计查找 的逻辑,方法是设置一个布尔标志来指示您是否正在查找它。
  • 你能给我一个代码的答案,以便我可以尝试吗?

标签: python


【解决方案1】:
  1. 建议:使用上下文管理器:

    with open(filename, 'r') as file:
        ...
    
  2. 建议:按垃圾方式进行读取和处理(目前,您只需一步读取文件,然后“逐行”遍历列表):

    for chunk in file.read(number_of_bytes_to_read):
        my_function(chunk)
    

当然,这样你必须注意正确的 xml 标签开始/结束。

替代方案:寻找 XML Parser 包。我很确定有一个可以分块处理文件,包括正确的标签处理。

【讨论】:

    【解决方案2】:

    首先,您不应该自己确定总行数或一次读取整个文件 如果你不需要。使用像this 这样的循环,您已经节省了一些时间。 另外考虑使用readlines()http://stupidpythonideas.blogspot.de/2013/06/readlines-considered-silly.html

    考虑到您正在使用 XML 元素,可能会考虑使用一个库来简化此操作。尤其是写作。

    【讨论】:

      【解决方案3】:

      您可以使用joblib 包使用并行处理来加速。假设您有一个名为 files 的文件列表,其结构如下:

      import ...
      from joblib import Parallel, delayed
      
      def read_the_file(file):
          ...
      
      if __name__ == '__main__':
      
          n = 8 # number of processors
          Parallel(n_jobs=n)(delayed(read_the_file)(file) for file in files)
      

      【讨论】:

      • 我担心 I/O 是瓶颈。并行处理不会有太大帮助。
      • 我同意 - 也许这可以与改进文件 I/O 方面一起使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 2020-11-12
      • 2017-05-29
      • 2021-09-02
      • 2014-05-19
      • 2020-08-20
      相关资源
      最近更新 更多