Concatenando múltiples archivos csv en un solo csv con el mismo encabezado – Python

Actualmente estoy usando el siguiente código para importar 6,000 archivos csv (con encabezados) y exportarlos a un solo archivo csv (con una sola fila de encabezado).

#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.") 

Este código funciona bien, pero es lento. El proceso puede demorar hasta 2 días.

Me dieron un script de una sola línea para la línea de comandos de Terminal que hace lo mismo (pero sin encabezados). Esta secuencia de comandos tarda 20 segundos.

  for f in *.csv; do cat "`pwd`/$f" | tail -n +2 >> merged.csv; done 

¿Alguien sabe cómo puedo acelerar el primer script de Python? Para reducir el tiempo, he pensado en no importarlo en un DataFrame y simplemente en concatenar los CSV, pero no puedo resolverlo.

Gracias.

Si no necesita el CSV en la memoria, solo copie de entrada a salida, será mucho más barato evitar el análisis en absoluto y copiar sin acumular en la memoria:

 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.") 

Eso es; shutil.copyfileobj maneja copiar los datos de manera eficiente, reduciendo drásticamente el trabajo a nivel de Python para analizar y reserializar.

Esto supone que todos los archivos CSV tienen el mismo formato, encoding, finales de línea, etc., y el encabezado no contiene nuevas líneas integradas, pero si ese es el caso, es mucho más rápido que las alternativas.

¿Estás obligado a hacer esto en Python? Si está dispuesto a hacer esto completamente en shell, todo lo que debe hacer es primero cat la fila del encabezado desde un archivo .csv de entrada seleccionado al azar en merged.csv antes de ejecutar su línea de una sola línea:

 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 

No necesitas pandas para esto, solo el simple módulo csv funcionaría bien.

 import csv df_out_filename = 'df_out.csv' write_headers = True with open(df_out_filename, 'wb') as fout: writer = csv.writer(fout) for filename in allFiles: with open(filename) as fin: reader = csv.reader(fin) headers = reader.next() if write_headers: write_headers = False # Only write headers once. writer.writerow(headers) writer.writerows(reader) # Write all remaining rows.