Fügen Sie einer CSV-Datei einen Python-Header hinzu

85

Ich habe ein Python-Skript geschrieben, in dem zwei CSV-Dateien zusammengeführt werden, und jetzt möchte ich der endgültigen CSV-Datei einen Header hinzufügen. Ich habe versucht, den hier gemeldeten Vorschlägen zu folgen, und habe den folgenden Fehler erhalten : expected string, float found. Was ist der pythonischste Weg, um dies zu beheben?

Hier ist der Code, den ich verwende:

import csv

with open('combined_file.csv', 'w', newline='') as outcsv:
    writer = csv.DictWriter(outcsv, fieldnames = ["Date", "temperature 1", "Temperature 2"])
    writer.writeheader()

    with open('t1.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row + [0.0] for row in reader)

    with open('t2.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row[:1] + [0.0] + row[1:] for row in reader)
albus_c
quelle
Wie viele Spalten schreiben Sie in Ihre CSV-Datei? Könnten Sie bitte in Ihrer Frage 1. Eingabeformat Ihrer Datei 2. Ausgabeformat
nio
@nio: Ein großer Teil des Codes stammt aus dieser vorherigen Frage des OP
Martijn Pieters

Antworten:

115

Die DictWriter()Klasse erwartet Wörterbücher für jede Zeile. Wenn Sie nur einen ersten Header schreiben wollten, verwenden Sie einen regulären Header csv.writer()und übergeben Sie den Header in einer einfachen Zeile:

import csv

with open('combined_file.csv', 'w', newline='') as outcsv:
    writer = csv.writer(outcsv)
    writer.writerow(["Date", "temperature 1", "Temperature 2"])

    with open('t1.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row + [0.0] for row in reader)

    with open('t2.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row[:1] + [0.0] + row[1:] for row in reader)

Die Alternative wäre, beim Kopieren über Ihre Daten Wörterbücher zu generieren:

import csv

with open('combined_file.csv', 'w', newline='') as outcsv:
    writer = csv.DictWriter(outcsv, fieldnames = ["Date", "temperature 1", "Temperature 2"])
    writer.writeheader()

    with open('t1.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows({'Date': row[0], 'temperature 1': row[1], 'temperature 2': 0.0} for row in reader)

    with open('t2.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows({'Date': row[0], 'temperature 1': 0.0, 'temperature 2': row[1]} for row in reader)
Martijn Pieters
quelle
1
Warum werden die Dateien im Binärmodus geöffnet? Die CSV-Dateien sind offensichtlich Text und kein Binärformat. Dies kann auf Windows-Systemen zu Problemen führen.
pcarter
3
@pcarter: Unter Python 2 löst das Öffnen einer Datei im Textmodus unter Windows Zeilenumbrüche aus, die nicht mit dem CSV-Format kompatibel sind. Das csvModul möchte daher Zeilenumbrüche direkt verarbeiten (mit \nund \r\nnach Bedarf), was bedeutet, dass Sie die Datei im Binärmodus öffnen müssen. Siehe csv.reader()Dokumentation : Wenn csvfile ein Dateiobjekt ist, muss es auf Plattformen, auf denen dies einen Unterschied macht, mit dem Flag 'b' geöffnet werden. . In Python 3 würden Sie stattdessen die newline=''Option verwenden.
Martijn Pieters
Das funktioniert, witzige Sache: Wenn die Datei im aModus geöffnet writer.writeheader()wird, wird der Header zweimal aufgeschrieben , obwohl die Header-Zeile bereits geschrieben wurde!
Loretoparisi
2
@loretoparisi: natürlich tut es. Nicht verwenden, writer.writeheader()wenn an eine vorhandene Datei angehängt wird. Das csv.writer()Objekt kann nicht erkennen, dass Sie Daten in eine vorhandene Datei schreiben.
Martijn Pieters
In Python 3 muss die Datei mit der Option 'w' geöffnet werden. Die Binärdatei funktioniert nicht. Es wäre nützlich, dies in der Antwort zu erwähnen. Ich habe diesen Unterschied hier gefunden: stackoverflow.com/questions/34283178/…
Kristóf
6

Sie fügen nur eine zusätzliche Zeile hinzu, bevor Sie die Schleife ausführen. Diese Zeile enthält den Namen Ihres CSV-Dateikopfs.

schema = ['a','b','c','b']
row = 4
generators = ['A','B','C','D']
with open('test.csv','wb') as csvfile:    
     writer = csv.writer(csvfile, delimiter=delimiter)
# Gives the header name row into csv
     writer.writerow([g for g in schema])   
#Data add in csv file       
     for x in xrange(rows):
         writer.writerow([g() for g in generators])
Mitul Panchal
quelle
3

Das hat bei mir funktioniert.

header = ['row1', 'row2', 'row3']
some_list = [1, 2, 3]
with open('test.csv', 'wt', newline ='') as file:
    writer = csv.writer(file, delimiter=',')
    writer.writerow(i for i in header)
    for j in some_list:
        writer.writerow(j)
saggzz
quelle
1
Die Verwendung einer Datei als Variable ist keine gute Idee. Zeile 3. Verwenden Sie stattdessen csvfile oder eine andere.
Gorgonzola