【问题标题】:How to split a big file(5GB) into small files according to its contents?如何根据内容将大文件(5GB)拆分为小文件?
【发布时间】:2018-12-18 12:46:22
【问题描述】:

我有 100 个大文件,每个大约 5GB。 我需要根据其内容将它们拆分为文件。 大文件有很多行,每一行都是这样的

{"task_op_id": 143677789, "task_op_time": 1530927931, "task_op_tag": 1, "create_time": 1530923701, "status": 2}

而我需要根据task_op_id拆分内容,每个大文件有350个不同的task_op_id,所以每个应该生成350个不同的小文件,每个小文件都有相同的task_op_id内容。

我试过的方法是:

def split_to_id_file(original_file):
    destination_file = 'processed_data2/data_over_one_id/break_into_ids/'
    with open(original_file) as f1:
        for line in f1:
            data_dict = json.loads(line)
            task_op_id = data_dict['task_op_id']
            with open(destination_file+str(task_op_id), 'a+') as f2:
                json.dump(data_dict, f2, ensure_ascii=False)
                f2.write('\n')
# multiprocessing with pool
def multiprocessing_pool(workers_number, job, files_list):
    p = Pool(workers_number)
    p.map(job, files_list)


def main():
    input_path = 'processed_data2/data_over_one_id'
    files_list = [join(input_path, f) for f in listdir(input_path)
              if isfile(join(input_path, f))
              and join(input_path, f).split('/')[-1].startswith('uegaudit')]
    multiprocessing_pool(80, split_to_id_file, files_list)


if __name__ == '__main__':
    main()

但是速度太慢,处理10GB数据需要2小时。

那么有没有更好的方法来处理数据?

非常感谢您的帮助。

【问题讨论】:

  • 至少不重新格式化 JSON 中的行可能会加快速度。只需将line 写入新文件即可。
  • 您可以尝试使用 Pandas 库读取数据块,然后对其进行组织。顺便说一句,如果您的代码已经可以运行并且您想要改进它,那么正确的去处是 Code Review (codereview.stackexchange.com)。 Stack Overflow 的重点是修复非工作代码 :)
  • 打开和关闭目标文件的每一行。分批写,会加快速度。

标签: python json file


【解决方案1】:

我推测主要的耗时过程是文件 IO 操作。你能分解运行时间并检查一下吗?

另一个原因可能是 JSON 解析器。查看this 线程了解更多信息。

【讨论】:

    【解决方案2】:

    你能对这些文件进行排序吗? 如果是,请尝试不要将每一行解析为 JSON,只解析具有新 ID 的行。

    这样的?

    def get_id(json_line): 
      data_dict = json.loads(json_line)
      return data_dict['task_op_id']
    
    def split_to_id_file(original_file):
      current_id = 'blabla_xxxxxxxx'
      destination_file = 'processed_data2/data_over_one_id/break_into_ids/'
      with open(original_file) as f1:
        for line in f1:
            if current_id not in line:
              if not f2.closed:
                f2.close()
              task_op_id = get_id(line)
              current_id = "\"task_op_id\": " + task_op_id
              f2 = open(destination_file+str(task_op_id), 'a+')
            f2.write(line+'\n')
    

    【讨论】:

      猜你喜欢
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 2019-09-23
      • 2010-11-30
      • 2017-04-27
      • 2015-03-24
      相关资源
      最近更新 更多