Leute, ich habe hier 200 separate CSV-Dateien mit den Namen SH (1) bis SH (200). Ich möchte sie in einer einzigen CSV-Datei zusammenführen. Wie kann ich es tun?
Leute, ich habe hier 200 separate CSV-Dateien mit den Namen SH (1) bis SH (200). Ich möchte sie in einer einzigen CSV-Datei zusammenführen. Wie kann ich es tun?
Antworten:
Wie Ghostdog74 sagte, aber diesmal mit Headern:
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()
f.__next__()
stattdessen f.next()
in python3.x verwenden.
with open
Syntax verwenden und vermeiden, .close()
die Dateien manuell zu bearbeiten.
f.next()
und f.__next__()
? Wenn ich das erstere benutze, habe ich'_io.TextIOWrapper' object has no attribute 'next'
fout.write(line)
ich tun würde:if line[-1] != '\n': line += '\n'
Warum kannst du nicht einfach sed 1d sh*.csv > merged.csv
?
Manchmal muss man nicht einmal Python verwenden!
Verwenden Sie die akzeptierte StackOverflow-Antwort , um eine Liste der CSV-Dateien zu erstellen, die Sie anhängen möchten, und führen Sie dann diesen Code aus:
import pandas as pd
combined_csv = pd.concat( [ pd.read_csv(f) for f in filenames ] )
Und wenn Sie es in eine einzelne CSV-Datei exportieren möchten, verwenden Sie Folgendes:
combined_csv.to_csv( "combined_csv.csv", index=False )
fout=open("out.csv","a")
for num in range(1,201):
for line in open("sh"+str(num)+".csv"):
fout.write(line)
fout.close()
Ich werde nur ein weiteres Codebeispiel im Warenkorb durchgehen
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)
Es kommt darauf an, was Sie unter "Zusammenführen" verstehen - haben sie dieselben Spalten? Haben sie Header? Wenn sie beispielsweise alle die gleichen Spalten und keine Header haben, ist eine einfache Verkettung ausreichend (öffnen Sie die Zieldatei zum Schreiben, durchlaufen Sie die Quellen, die jeweils zum Lesen geöffnet sind , und verwenden Sie shutil.copyfileobj von der Quelle zum Lesen zum Öffnen in die Ziel zum Schreiben öffnen, Quelle schließen, Schleife fortsetzen - Verwenden Sie die with
Anweisung, um das Schließen in Ihrem Namen durchzuführen. Wenn sie dieselben Spalten, aber auch Überschriften haben, benötigen Sie readline
für jede Quelldatei eine, mit Ausnahme der ersten, nachdem Sie sie zum Lesen geöffnet haben, bevor Sie sie in das Ziel kopieren, um die Überschriftenzeile zu überspringen.
Wenn die CSV-Dateien nicht alle die gleichen Spalten haben, müssen Sie definieren, in welchem Sinne Sie sie "zusammenführen" (wie ein SQL JOIN? Oder "horizontal", wenn sie alle die gleiche Anzahl von Zeilen haben? Etc usw. ) - Es fällt uns schwer zu erraten, was Sie in diesem Fall meinen.
Wenn die zusammengeführte CSV in Python verwendet werden soll, verwenden Sie einfach glob
, um eine Liste der Dateien abzurufen, an die fileinput.input()
über das files
Argument übergeben werden soll, und verwenden Sie dann das csv
Modul, um alles auf einmal zu lesen.
Ganz einfach, alle Dateien in einem Verzeichnis zu kombinieren und zusammenzuführen
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)
ODER du könntest es einfach tun
cat sh*.csv > merged.csv
Sie können CSV importieren und dann alle CSV-Dateien, die sie lesen, in einer Liste durchlaufen. Schreiben Sie dann die Liste wieder auf die Festplatte.
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))
Das Obige ist nicht sehr robust, da es weder eine Fehlerbehandlung aufweist noch offene Dateien schließt. Dies sollte funktionieren, unabhängig davon, ob die einzelnen Dateien eine oder mehrere Zeilen mit CSV-Daten enthalten. Ich habe diesen Code auch nicht ausgeführt, aber er sollte Ihnen eine Vorstellung davon geben, was zu tun ist.
Über die Lösung, die @Adders gemacht und später von @varun verbessert hat, habe ich auch einige kleine Verbesserungen implementiert, sodass die gesamte zusammengeführte CSV nur den Hauptheader enthält:
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()
Freundliche Grüße!!!
Sie können einfach die eingebaute csv
Bibliothek verwenden. Diese Lösung funktioniert auch dann, wenn einige Ihrer CSV-Dateien im Gegensatz zu den anderen Antworten mit den höchsten Stimmen leicht unterschiedliche Spaltennamen oder Überschriften haben.
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)
Die zusammengeführte Datei enthält alle möglichen Spalten ( header_keys
), die in den Dateien gefunden werden können. Alle fehlenden Spalten in einer Datei werden als leer / leer gerendert (wobei die restlichen Daten der Datei erhalten bleiben).
Hinweis:
csv
Bibliothek weiterhin verwenden , aber anstatt DictReader
& zu verwenden DictWriter
, müssen Sie mit dem grundlegenden reader
& arbeiten writer
.merged_rows
Liste) gespeichert wird .Ich habe geändert, was @wisty gesagt hat, um mit Python 3.x zu arbeiten. Für diejenigen unter Ihnen, die Codierungsprobleme haben, verwende ich auch das OS-Modul, um eine harte Codierung zu vermeiden
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()
Hier ist ein Skript:
SH1.csv
zuSH200.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())
Wistys Antwort für Python3 wird aktualisiert
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()
Angenommen, Sie haben 2 csv
Dateien wie diese:
csv1.csv:
id,name
1,Armin
2,Sven
csv2.csv:
id,place,year
1,Reykjavik,2017
2,Amsterdam,2018
3,Berlin,2019
und Sie möchten, dass das Ergebnis wie folgt aussieht: csv3.csv:
id,name,place,year
1,Armin,Reykjavik,2017
2,Sven,Amsterdam,2018
3,,Berlin,2019
Dann können Sie das folgende Snippet verwenden, um dies zu tun:
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)
Mit Hilfe einer Schleife können Sie für mehrere Dateien das gleiche Ergebnis erzielen wie in Ihrem Fall (200 CSV-Dateien).
Wenn die Dateien nicht in der richtigen Reihenfolge nummeriert sind, gehen Sie wie folgt vor: Python 3.6 auf Windows-Computern:
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)
Eine einfach zu bedienende Funktion:
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)
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()