将多个csv文件连接到具有相同标头的单个csv - Python

mat*_*ack 12 python csv terminal concatenation pandas

我目前正在使用以下代码导入6,000个csv文件(带标题)并将它们导出到单个csv文件中(带有单个标题行).

#import csv files from folder
path =r'data/US/market/merged_data'
allFiles = glob.glob(path + "/*.csv")
stockstats_data = pd.DataFrame()
list_ = []

for file_ in allFiles:
    df = pd.read_csv(file_,index_col=None,)
    list_.append(df)
    stockstats_data = pd.concat(list_)
    print(file_ + " has been imported.")
Run Code Online (Sandbox Code Playgroud)

这段代码工作正常,但速度很慢.处理最多可能需要2天.

我得到了终端命令行的单行脚本,它执行相同的操作(但没有标题).这个脚本需要20秒.

 for f in *.csv; do cat "`pwd`/$f" | tail -n +2 >> merged.csv; done 
Run Code Online (Sandbox Code Playgroud)

有谁知道如何加速第一个Python脚本?为了缩短时间,我考虑过不将它导入DataFrame并只是连接CSV,但我无法弄清楚.

谢谢.

Sha*_*ger 15

如果你不需要内存中的CSV,只需要从输入复制到输出,那么避免解析就会便宜很多,并且在没有在内存中构建的情况下进行复制:

import shutil

#import csv files from folder
path = r'data/US/market/merged_data'
allFiles = glob.glob(path + "/*.csv")
with open('someoutputfile.csv', 'wb') as outfile:
    for i, fname in enumerate(allFiles):
        with open(fname, 'rb') as infile:
            if i != 0:
                infile.readline()  # Throw away header on all but first file
            # Block copy rest of file from input to output without parsing
            shutil.copyfileobj(infile, outfile)
            print(fname + " has been imported.")
Run Code Online (Sandbox Code Playgroud)

而已; shutil.copyfileobj处理有效复制数据,大大减少了Python级别的工作来解析和重新序列化.

这假设所有CSV文件具有相同的格式,编码,行结尾等,并且标题不包含嵌入的换行符,但如果是这种情况,则它比替代品快得多.

  • @vikrantrana:这是一个完全不同的问题,不适合在评论中回答,也不适合回答 OP 的问题。假设 [关于这个主题的许多问题](https://stackoverflow.com/search?q=python+split+csv) 没有涵盖它,请随意就该主题提出您自己的问题。不过,它需要更多的细节来回答(例如,您是否按行数、字节数等进行拆分),并且需要 `csv` 模块(因为您需要它来正确分隔行)。 (2认同)

Pet*_*ler 6

您是否需要在Python中执行此操作?如果您愿意完全在shell中执行此操作,那么您需要做的就是在运行单行cat程序merged.csv之前首先从随机选择的输入.csv文件中添加标题行:

cat a-randomly-selected-csv-file.csv | head -n1 > merged.csv
for f in *.csv; do cat "`pwd`/$f" | tail -n +2 >> merged.csv; done 
Run Code Online (Sandbox Code Playgroud)