【问题标题】:Fastest way to stack CSV files堆叠 CSV 文件的最快方法
【发布时间】:2017-07-08 20:13:47
【问题描述】:

我有 10 个具有相同列和数据类型的 csv 文件。堆叠它们最快/最有效的方法是什么?

CSV1:

col1 | col2 | col3
  1  |  'a' |  0.1
  2  |  'b' |  0.8

CSV2:

col1 | col2 | col3
  3  |  'c' |  0.4
  4  |  'd' |  0.3

我可以用Pandas 读入它们并重复df.append 但这似乎很慢,因为我必须将所有内容读入内存,如果文件非常大,可能需要很长时间。想知道我是否可以使用 bash 命令或其他 Python 包更快地做到这一点。

我不希望使用具有任何严重依赖关系或需要编译的东西。

附:如果解决方案还可以自动处理存在于一个数据集中而不是另一个数据集中的列,则可以加分。

【问题讨论】:

标签: python bash csv append


【解决方案1】:

正如@zwer 在comment to another answer 中正确指出的那样,如果输入 CSV 错过了最后一行的换行符,此解决方案将无法正常工作。


使用bashsed 的解决方案(假设所有文件都具有相同的列/分隔符并且都包含标题行):

concat_csv_files

#!/usr/bin/env bash

head -n1 "$1"
for f do
    sed -e 1d "$f" # or: tail -n+2 "$f"
done

例子:

concat_csv_files csv* > stacked.csv

【讨论】:

    【解决方案2】:

    使用headtail 的解决方案

    head -n1 a.log > output.log
    for f in a.log b.log; do tail -n+2 $f; done >> output.log
    

    如果您的输入文件末尾可能没有换行符,您必须按照@zwar 的说明手动添加它。这个问题的许多解决方案都给出了in this thread。我最喜欢在这种情况下工作的是

    head -n1 a.log > output.log
    for f in a.log b.log
    do
      tail -n+2 $f
      [ -n "$(tail -c1 $f)" ] && echo ""
    done >> output.log
    

    【讨论】:

    • 小心这个(就像 head/sed 一样) - 如果您的任何 CSV 文件(最后一个除外)在最后一行没有换行符(对于CSV),这会弄乱输出。
    • @zwer 感谢您的提示!我为该问题添加了解决方案
    • tail -c1 "$f" 总是会输出一个字节(除非文件完全为空),无论该字节是否(部分)行尾序列。
    • @chepner 是的,确实如此,但测试会以不同的方式处理这些结果
    • @Chris 您不应该将标头通过管道传输到 csv2.csv,而是将 out_csv.csv 传输到
    【解决方案3】:

    纯 Python 解决方案:

    csv_in = ["csv1.csv", "csv2.csv"]  # paths of CSVs to 'concentrate'
    csv_out = "output.csv"
    
    skip_header = False
    with open(csv_out, "w") as dest:
        for csv in csv_in:
            with open(csv, "r") as src:
                if skip_header:  # skip the CSV header in consequent files
                    next(src)
                for line in src:
                    dest.write(line)
                    if line[-1] != "\n":  # if not present, write a new line after each row
                        dest.write("\n")
                skip_header = True  # make sure only the first CSV header is included
    

    要合并具有不同列数的数据,您必须至少部分解析 CSV。

    【讨论】:

      【解决方案4】:

      如果你想做一个 python 解决方案

      import csv
      
      my_files = ['file_one.csv', 'file_two.csv']
      final_file = []
      for fi in files:
           with open(fi, r) as f:
                reader = csv.reader(f, delimiter='|')
                for row in reader:
                     final_file.append(row)
      
      #write out final file
      with open('final_file.csv', 'w') as out:
          for line in final_file:
               out.write('|'.join(line))
               out.write('\n')
      

      【讨论】:

        【解决方案5】:

        这是另一个纯 Python 解决方案。这个想法是使用 glob 来构建要处理的文件列表,然后将它们单独导入到单独的 pandas 数据帧中(并将每个数据帧添加到列表中)。然后将数据帧列表连接成一个。您只想这样做一次,而不是使用重复的 df.append 调用(它太慢了)。我发现为每一列指定数据类型有助于加快速度。

        import os
        import glob
        import numpy as np
        import pandas as pd
        
        def process_csv_file(f):
        
            print("Processing file {}".format(f))
        
            # check if it's an empty file (have to be able to append an empty dataframe)
            # specifying the datatypes speeds up the process because pandas doesn't have to guess.
            if os.stat(f).st_size > 0:
                df = pd.read_csv(f, sep = ',', dtype = {'col1' : str, 'col2' : float}, memory_map=True)
            else:
                df = pd.DataFrame()
        
            return(df)
        
        csv_files = glob.glob(indir +'/**/' + '*.csv', recursive = True)
        print ("Found {} files to parse.".format(len(csv_files)))
        frames = [process_csv_file(f) for f in csv_files]
        
        csv_df = pd.concat(frames)
        

        【讨论】:

        • 如果整个数据不适合内存,而其他数据流式传输数据,则此问题是一个问题。我没有意识到迭代追加比 concat 慢!
        • 非常正确。当我第一次写这篇文章时,我的目标是构建一个包含所有内容的数据框,这样我就可以做进一步的 pandas 操作。仅与您的请求无关。
        猜你喜欢
        • 2019-07-31
        • 2015-09-13
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        • 2014-09-26
        • 1970-01-01
        • 2019-08-13
        • 2016-05-19
        相关资源
        最近更新 更多