【问题标题】:How can I split a large file csv file (7GB) in Python如何在 Python 中拆分大文件 csv 文件(7GB)
【发布时间】:2013-11-30 18:44:59
【问题描述】:

我有一个 7GB csv 文件,我想将其拆分成更小的块,以便在笔记本上用 Python 进行分析时可读且速度更快。我想从中获取一小部分,大概 250MB,我该怎么做呢?

【问题讨论】:

    标签: python csv split


    【解决方案1】:

    您不需要 Python 来拆分 csv 文件。使用你的外壳:

    $ split -l 100 data.csv
    

    data.csv 拆分为 100 行的块。

    【讨论】:

    • 注意:这不会使每个文件的标题保持不变。以防万一您想要每个块的标题字段。
    • 对于 csv 文件来说不是万无一失的。如果长文本引号转义值中有换行符,则行可能会在两个文件之间拆分。
    • 最后一个参数可以添加到具有有用名称split -l 100 data.csv data_split_的前缀文件中
    • 如果我有同样的问题并从谷歌来到这里,我需要如何处理您的回答?问题是:“如何用 Python 分割大文件?” (**不是通过 CMD 或 bush 或其他一切......):(
    【解决方案2】:

    我不得不做类似的任务,并使用了 pandas 包:

    for i,chunk in enumerate(pd.read_csv('bigfile.csv', chunksize=500000)):
        chunk.to_csv('chunk{}.csv'.format(i), index=False)
    

    【讨论】:

    • 我不认为这个解决方案很好。我有一个 2 Gb(16m 行),pandas 无法在内存中处理它。分块并不意味着您不会将整个 df 加载到内存 (RAM) 中,它只是意味着您一次使用 chunksize 中指定的行数读取它。
    • 这是一个很好的答案。但请注意,这会在原始 csv 中添加一个额外的索引列。
    • "这会在原始 csv 中添加一个额外的索引列。" - 现在已通过添加 Index=False 修复此问题。
    【解决方案3】:

    这是我用来将文件 data.csv 拆分为多个 CSV 部分文件的小 Python 脚本。部分文件的数量可以通过chunk_size(每个部分文件的行数)来控制。

    原始文件的标题行(列名)被复制到每个部分的 CSV 文件中。

    它适用于大文件,因为它使用readline() 一次读取一行,而不是一次将整个文件加载到内存中。

    #!/usr/bin/env python3
    
    def main():
        chunk_size = 9998  # lines
    
        def write_chunk(part, lines):
            with open('data_part_'+ str(part) +'.csv', 'w') as f_out:
                f_out.write(header)
                f_out.writelines(lines)
    
        with open('data.csv', 'r') as f:
            count = 0
            header = f.readline()
            lines = []
            for line in f:
                count += 1
                lines.append(line)
                if count % chunk_size == 0:
                    write_chunk(count // chunk_size, lines)
                    lines = []
            # write remainder
            if len(lines) > 0:
                write_chunk((count // chunk_size) + 1, lines)
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

    • @GooDeeJAY - 这是一个很好的答案,代码是不言自明的。好的代码可以“说话”而不需要大量的叙述。
    • @Powers 我完全同意你的看法。但是,我也相信(这个社区认为我)在代码上方应该有某种解释性文字。我看到他已经编辑了他的帖子并添加了一些解释性文字。好像那个时候我忘了“关注”帖子,所以当他编辑他的帖子时没有收到通知,删除我的评论。
    【解决方案4】:

    也许是这样的?

    #!/usr/local/cpython-3.3/bin/python
    
    import csv
    
    divisor = 10
    
    outfileno = 1
    outfile = None
    
    with open('big.csv', 'r') as infile:
        for index, row in enumerate(csv.reader(infile)):
            if index % divisor == 0:
                if outfile is not None:
                    outfile.close()
                outfilename = 'big-{}.csv'.format(outfileno)
                outfile = open(outfilename, 'w')
                outfileno += 1
                writer = csv.writer(outfile)
            writer.writerow(row)
    

    【讨论】:

    • 这确实拆分了 CSV,但是输出 csv 中的每一行之间都有空白行。
    【解决方案5】:

    查看file对象上的Python docsopen(filename)返回的对象-您可以选择read指定的字节数,或使用readline一次处理一行。

    【讨论】:

      【解决方案6】:

      我同意@jonrsharpe readline 应该能够一次读取一行,即使对于大文件也是如此。

      如果您正在处理大型 csv 文件,我建议您使用pandas.read_csv。我经常将它用于相同的目的,并且总是觉得它很棒(而且速度很快)。需要一些时间来习惯 DataFrames 的概念。但是一旦你克服了这一点,它就会大大加快像你这样的大型操作。

      希望对您有所帮助。

      【讨论】:

      • pandas 实际上是处理大型 csv 文件的一个非常糟糕的解决方案,因为它们只能真正处理一次可以存储在 RAM 中的数据。会推荐其他库,例如 Dask。 medium.com/analytics-vidhya/…
      【解决方案7】:

      此图显示了其他海报概述的不同方法的运行时差异(在 8 核机器上,将具有 1180 万行数据的 2.9 GB 文件拆分为约 290 个文件)。

      shell 方法来自 Thomas Orozco,Python 方法来自 Roberto,Pandas 方法来自 Quentin Febvre,这是 Dask sn-p:

      ddf = dd.read_csv("../nyc-parking-tickets/Parking_Violations_Issued_-_Fiscal_Year_2015.csv", blocksize=10000000, dtype=dtypes)
      ddf.to_csv("../tmp/split_csv_dask")
      

      我推荐使用 Dask 来分割文件,尽管它不是最快的,因为它是最灵活的解决方案(您可以写出不同的文件格式、在写入之前执行处理操作、轻松修改压缩格式等)。 Pandas 方法几乎同样灵活,但无法对整个数据集进行处理(例如在写入之前对整个数据集进行排序)。

      Bash / 本机 Python 文件系统操作显然更快,但这不是我在拥有大型 CSV 时通常要寻找的。我通常有兴趣将大型 CSV 拆分为更小的 Parquet 文件,以进行高性能的生产数据分析。我通常不在乎实际拆分是否需要几分钟。我对准确拆分更感兴趣。

      我写了一篇博文,更详细地讨论了这个问题。您可能可以通过 Google 搜索并找到该帖子。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-29
        • 2014-02-17
        相关资源
        最近更新 更多