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)

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)

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])

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)

1
Die Verwendung einer Datei als Variable ist keine gute Idee. Zeile 3. Verwenden Sie stattdessen csvfile oder eine andere.
Gorgonzola
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.