2010-03-25 27 views
37

Chicos, aquí tengo 200 archivos csv separados nombrados desde SH (1) a SH (200). Quiero fusionarlos en un solo archivo csv. ¿Cómo puedo hacerlo?cómo fusionar 200 archivos csv en Python

+2

¿De qué manera los fusionarías? (Concatenar líneas, ...) – tur1ng

+5

¿Cómo quieres que se fusionen? Cada línea en un archivo CSV es una fila. Entonces, una opción simple es concatenar todos los archivos juntos. –

+0

Cada archivo tiene dos columnas. Quiero fusionarlos en un solo archivo con dos columnas consecutivamente. – Chuck

Respuesta

48

Como ghostdog74 dijo, pero esta vez con los encabezados:

fout=open("out.csv","a") 
# first file: 
for line in open("sh1.csv"): 
    fout.write(line) 
# now the rest:  
for num in range(2,201): 
    f = open("sh"+str(num)+".csv") 
    f.next() # skip the header 
    for line in f: 
     fout.write(line) 
    f.close() # not really needed 
fout.close() 
+0

gracias por esta solución! exactamente lo que busqué! – Riccardo

+0

puede usar 'f .__ next __()' en su lugar si 'f.next()' en python3.x. –

3

Si el fusionada CSV va a ser utilizado en Python entonces sólo tiene que utilizar glob para obtener una lista de los archivos que pasar a través de fileinput.input() el argumento files, a continuación, utilizar el módulo csv leerlo todo de una sola vez.

12
fout=open("out.csv","a") 
for num in range(1,201): 
    for line in open("sh"+str(num)+".csv"): 
     fout.write(line)  
fout.close() 
10

Depende de lo que quiere decir con "fusión" - ¿tienen las mismas columnas? ¿Tienen encabezados? Por ejemplo, si todas tienen las mismas columnas y no hay encabezados, la concatenación simple es suficiente (abra el archivo de destino para escribir, recorra las fuentes que se abren para leer, use shutil.copyfileobj desde la fuente abierta para leer hasta la fuente abierta). para escribir el destino, cerrar la fuente, seguir haciendo un bucle - use la declaración with para cerrar en su nombre). Si tienen las mismas columnas, pero también encabezados, necesitará un readline en cada archivo de origen, excepto el primero, después de abrirlo para leerlo antes de copiarlo en el destino, para omitir la línea de encabezados.

Si los archivos CSV no tienen todas las mismas columnas, entonces necesita definir en qué sentido los está "fusionando" (como un JOIN de SQL u "horizontalmente" si todos tienen el mismo número de líneas ? etc, etc.) - es difícil para nosotros adivinar a qué te refieres en ese caso.

+0

Cada archivo tiene dos columnas con encabezados. Quiero fusionarlos en un solo archivo con dos columnas consecutivamente. – Chuck

1

Puede importar csv luego recorrer todos los archivos CSV y leerlos en una lista. Luego, vuelve a escribir la lista en el disco.

import csv 

rows = [] 

for f in (file1, file2, ...): 
    reader = csv.reader(open("f", "rb")) 

    for row in reader: 
     rows.append(row) 

writer = csv.writer(open("some.csv", "wb")) 
writer.writerows("\n".join(rows)) 

Lo anterior no es muy robusto ya que no tiene ningún error de manejo ni cierra ningún archivo abierto. Esto debería funcionar independientemente de si los archivos individuales tienen una o más filas de datos CSV en ellos. Además, no ejecuté este código, pero debería darte una idea de qué hacer.

29

¿Por qué no acaba de sed 1d sh*.csv > merged.csv?

¡A veces ni siquiera tiene que usar Python!

+9

En windows, C: \> copy * .csv merged.csv –

+1

Copie la información de encabezado de un archivo: sed -n 1p some_file.csv> fusionado_archivo.csv Copie todo menos la última línea de todos los demás archivos: sed 1d * .csv >> merged_file.csv – behas

+1

@blinsay Añade el encabezado en cada archivo CSV al archivo fusionado también. – Mina

10

Voy a través de otro ejemplo de código en la cesta

from glob import glob 

with open('singleDataFile.csv', 'a') as singleFile: 
    for csvFile in glob('*.csv'): 
     for line in open(csvFile, 'r'): 
      singleFile.write(line) 
+2

@Andy No veo la diferencia entre Stackoverflow y me recuerda que vote una respuesta y que le recuerde a las personas que compartan su agradecimiento (al votar) si consideran que mi respuesta es útil. Sé que esto no es Facebook y no soy un cazador similar ... – Norfeldt

+0

Ha sido [discutido] (http://meta.stackexchange.com/a/63440/186281) [previamente] (http: // meta.stackexchange.com/a/194063/186281), y cada vez que se ha [juzgado] (http://meta.stackexchange.com/questions/167155/comments-asking-for-upvotes-accepts) inaceptable. – Andy

+1

vea @adders corrected code below – mattrweaver

3

Un ligero cambio en el código anterior, ya que en realidad no funciona correctamente.

Debe ser como sigue ...

from glob import glob 

with open('main.csv', 'a') as singleFile: 
    for csv in glob('*.csv'): 
     if csv == 'main.csv': 
      pass 
     else: 
      for line in open(csv, 'r'): 
       singleFile.write(line) 
1

Muy fácil de combinar todos los archivos en un directorio y fusionarlos

import glob 
import csv 


# Open result file 
with open('output.txt','wb') as fout: 
    wout = csv.writer(fout,delimiter=',') 
    interesting_files = glob.glob("*.csv") 
    h = True 
    for filename in interesting_files: 
     print 'Processing',filename 
     # Open and process file 
     with open(filename,'rb') as fin: 
      if h: 
       h = False 
      else: 
       fin.next()#skip header 
      for line in csv.reader(fin,delimiter=','): 
       wout.writerow(line) 
8

Uso accepted StackOverflow answer para crear una lista de archivos CSV que desea añadir y luego ejecutar este código:

import pandas as pd 
combined_csv = pd.concat([ pd.read_csv(f) for f in filenames ]) 

Y si desea exportarlo a un solo archivo csv, use esto:

combined_csv.to_csv("combined_csv.csv", index=False) 
+0

@ wisty, @ Andy, supongamos que todos los archivos tienen títulos para cada fila, algunas filas con diferentes títulos. No hay encabezados para las 2 columnas en cada archivo. Cómo se puede fusionar, de modo que para cada archivo solo se agrega una columna. – Gathide

+0

¿Dónde se exporta el archivo? – dirtysocks45

+0

@ dirtysocks45, cambié la respuesta para hacer esto más explícito. – scottlittle

0

lo he modificado @wisty dice que trabajó con 3.x pitón, para aquellos de ustedes que tienen un problema de codificación, también uso módulo os para evitar de codificación duro

import os 
def merge_all(): 
    dir = os.chdir('C:\python\data\\') 
    fout = open("merged_files.csv", "ab") 
    # first file: 
    for line in open("file_1.csv",'rb'): 
     fout.write(line) 
    # now the rest: 
    list = os.listdir(dir) 
    number_files = len(list) 
    for num in range(2, number_files): 
     f = open("file_" + str(num) + ".csv", 'rb') 
     f.__next__() # skip the header 
     for line in f: 
      fout.write(line) 
     f.close() # not really needed 
    fout.close() 
0

Aquí es un script:

  • la concatenación de archivos CSV denominado SH1.csv-SH200.csv
  • Mantener las cabeceras
import glob 
import re 

# Looking for filenames like 'SH1.csv' ... 'SH200.csv' 
pattern = re.compile("^SH([1-9]|[1-9][0-9]|1[0-9][0-9]|200).csv$") 
file_parts = [name for name in glob.glob('*.csv') if pattern.match(name)] 

with open("file_merged.csv","wb") as file_merged: 
    for (i, name) in enumerate(file_parts): 
     with open(name, "rb") as file_part: 
      if i != 0: 
       next(file_part) # skip headers if not first file 
      file_merged.write(file_part.read())