Chicos, aquí tengo 200 archivos csv separados nombrados de SH (1) a SH (200). Quiero combinarlos en un solo archivo csv. ¿Cómo puedo hacerlo?
python
csv
merge
concatenation
Arrojar
fuente
fuente
Respuestas:
Como dijo ghostdog74, pero esta vez con 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()
fuente
f.__next__()
en su lugar si estáf.next()
en python3.x.with open
sintaxis y evitar la manipulación manual.close()
de los archivos.f.next()
yf.__next__()
? cuando uso el primero, obtuve'_io.TextIOWrapper' object has no attribute 'next'
fout.write(line)
que haría:if line[-1] != '\n': line += '\n'
¿Por qué no puedes simplemente
sed 1d sh*.csv > merged.csv
?¡A veces ni siquiera tienes que usar Python!
fuente
Use la respuesta aceptada de StackOverflow para crear una lista de archivos csv que desea agregar y luego ejecute 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 )
fuente
fout=open("out.csv","a") for num in range(1,201): for line in open("sh"+str(num)+".csv"): fout.write(line) fout.close()
fuente
Solo voy a ver otro ejemplo de código en la canasta
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)
fuente
Depende de lo que quiera decir con "fusión": ¿tienen las mismas columnas? ¿Tienen encabezados? Por ejemplo, si todos tienen las mismas columnas y no tienen encabezados, una simple concatenación es suficiente (abra el archivo de destino para escribir, recorra las fuentes abriendo cada una para leer, use shutil.copyfileobj de la fuente abierta para lectura en la destino abierto para escritura, cierre la fuente, siga repitiendo - use la
with
declaración para hacer el cierre en su nombre). Si tienen las mismas columnas, pero también encabezados, necesitará unreadline
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 todos las mismas columnas, entonces necesita definir en qué sentido los está "fusionando" (como un SQL JOIN? U "horizontalmente" si todos tienen el mismo número de líneas? Etc., etc. ) - es difícil para nosotros adivinar lo que quiere decir en ese caso.
fuente
Si el CSV combinado se va a usar en Python, solo utilícelo
glob
para obtener una lista de los archivos a los que pasar afileinput.input()
través delfiles
argumento, luego use elcsv
módulo para leerlo todo de una vez.fuente
Un ligero cambio en el código anterior, ya que en realidad no funciona correctamente.
Debería 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)
fuente
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)
fuente
Si está trabajando en linux / mac, puede hacerlo.
from subprocess import call script="cat *.csv>merge.csv" call(script,shell=True)
fuente
O, simplemente podrías hacer
fuente
Puede importar csv y luego recorrer todos los archivos CSV leyéndolos en una lista. Luego, vuelva 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 maneja errores ni cierra ningún archivo abierto. Esto debería funcionar independientemente de que los archivos individuales tengan 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.
fuente
Sobre la solución que hizo @Adders y luego mejorada por @varun, implementé algunas pequeñas mejoras y dejé todo el CSV combinado con solo el encabezado principal:
from glob import glob filename = 'main.csv' with open(filename, 'a') as singleFile: first_csv = True for csv in glob('*.csv'): if csv == filename: pass else: header = True for line in open(csv, 'r'): if first_csv and header: singleFile.write(line) first_csv = False header = False elif header: header = False else: singleFile.write(line) singleFile.close()
¡¡¡Atentamente!!!
fuente
Simplemente puede usar la
csv
biblioteca incorporada . Esta solución funcionará incluso si algunos de sus archivos CSV tienen nombres de columna o encabezados ligeramente diferentes, a diferencia de las otras respuestas más votadas.import csv import glob filenames = [i for i in glob.glob("SH*.csv")] header_keys = [] merged_rows = [] for filename in filenames: with open(filename) as f: reader = csv.DictReader(f) merged_rows.extend(list(reader)) header_keys.extend([key for key in reader.fieldnames if key not in header_keys]) with open("combined.csv", "w") as f: w = csv.DictWriter(f, fieldnames=header_keys) w.writeheader() w.writerows(merged_rows)
El archivo combinado contendrá todas las columnas posibles (
header_keys
) que se pueden encontrar en los archivos. Cualquier columna ausente en un archivo se representaría como en blanco / vacía (pero conservando el resto de los datos del archivo).Nota:
csv
biblioteca, pero en lugar de usarDictReader
&DictWriter
, tendrá que trabajar con elreader
& básicowriter
.merged_rows
lista).fuente
Modifiqué lo que @wisty dijo para trabajar con python 3.x, para aquellos de ustedes que tienen problemas de codificación, también uso el módulo os para evitar la codificación dura
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()
fuente
Aquí hay un guión:
SH1.csv
deSH200.csv
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())
fuente
Actualizando la respuesta de wisty para python3
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") next(f) # skip the header for line in f: fout.write(line) f.close() # not really needed fout.close()
fuente
Digamos que tiene 2
csv
archivos como estos:csv1.csv:
id,name 1,Armin 2,Sven
csv2.csv:
id,place,year 1,Reykjavik,2017 2,Amsterdam,2018 3,Berlin,2019
y desea que el resultado sea como este csv3.csv:
id,name,place,year 1,Armin,Reykjavik,2017 2,Sven,Amsterdam,2018 3,,Berlin,2019
Luego, puede usar el siguiente fragmento para hacerlo:
import csv import pandas as pd # the file names f1 = "csv1.csv" f2 = "csv2.csv" out_f = "csv3.csv" # read the files df1 = pd.read_csv(f1) df2 = pd.read_csv(f2) # get the keys keys1 = list(df1) keys2 = list(df2) # merge both files for idx, row in df2.iterrows(): data = df1[df1['id'] == row['id']] # if row with such id does not exist, add the whole row if data.empty: next_idx = len(df1) for key in keys2: df1.at[next_idx, key] = df2.at[idx, key] # if row with such id exists, add only the missing keys with their values else: i = int(data.index[0]) for key in keys2: if key not in keys1: df1.at[i, key] = df2.at[idx, key] # save the merged files df1.to_csv(out_f, index=False, encoding='utf-8', quotechar="", quoting=csv.QUOTE_NONE)
Con la ayuda de un bucle, puede lograr el mismo resultado para varios archivos que en su caso (200 archivos csv).
fuente
Si los archivos no están numerados en orden, adopte el método sin complicaciones a continuación: Python 3.6 en una máquina con Windows:
import pandas as pd from glob import glob interesting_files = glob("C:/temp/*.csv") # it grabs all the csv files from the directory you mention here df_list = [] for filename in sorted(interesting_files): df_list.append(pd.read_csv(filename)) full_df = pd.concat(df_list) # save the final file in same/different directory: full_df.to_csv("C:/temp/merged_pandas.csv", index=False)
fuente
Una función fácil de usar:
def csv_merge(destination_path, *source_paths): ''' Merges all csv files on source_paths to destination_path. :param destination_path: Path of a single csv file, doesn't need to exist :param source_paths: Paths of csv files to be merged into, needs to exist :return: None ''' with open(destination_path,"a") as dest_file: with open(source_paths[0]) as src_file: for src_line in src_file.read(): dest_file.write(src_line) source_paths.pop(0) for i in range(len(source_paths)): with open(source_paths[i]) as src_file: src_file.next() for src_line in src_file: dest_file.write(src_line)
fuente
import pandas as pd import os df = pd.read_csv("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data\\Sales_April_2019.csv") files = [file for file in os.listdir("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data") for file in files: print(file) all_data = pd.DataFrame() for file in files: df=pd.read_csv("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data\\"+file) all_data = pd.concat([all_data,df]) all_data.head()
fuente