Überspringen Sie die Header, wenn Sie eine CSV-Datei mit Python bearbeiten


208

Ich verwende den unten angegebenen Code, um eine CSV mit Python zu bearbeiten. Im Code aufgerufene Funktionen bilden den oberen Teil des Codes.

Problem: Ich möchte, dass der unten angegebene Code die Bearbeitung der CSV aus der 2. Zeile startet. Ich möchte, dass die 1. Zeile, die Überschriften enthält, ausgeschlossen wird. Im Moment werden die Funktionen nur in der 1. Zeile angewendet und meine Kopfzeile wird geändert.

in_file = open("tmob_notcleaned.csv", "rb")
reader = csv.reader(in_file)
out_file = open("tmob_cleaned.csv", "wb")
writer = csv.writer(out_file)
row = 1
for row in reader:
    row[13] = handle_color(row[10])[1].replace(" - ","").strip()
    row[10] = handle_color(row[10])[0].replace("-","").replace("(","").replace(")","").strip()
    row[14] = handle_gb(row[10])[1].replace("-","").replace(" ","").replace("GB","").strip()
    row[10] = handle_gb(row[10])[0].strip()
    row[9] = handle_oem(row[10])[1].replace("Blackberry","RIM").replace("TMobile","T-Mobile").strip()
    row[15] = handle_addon(row[10])[1].strip()
    row[10] = handle_addon(row[10])[0].replace(" by","").replace("FREE","").strip()
    writer.writerow(row)
in_file.close()    
out_file.close()

Ich habe versucht, dieses Problem durch Initialisieren der rowVariablen auf zu lösen , 1aber es hat nicht funktioniert.

Bitte helfen Sie mir bei der Lösung dieses Problems.


Antworten:


369

Ihre readerVariable ist iterierbar. Wenn Sie sie durchlaufen, rufen Sie die Zeilen ab.

Um ein Element vor Ihrer Schleife zu überspringen, rufen Sie einfach next(reader, None)den Rückgabewert auf und ignorieren Sie ihn.

Sie können Ihren Code auch ein wenig vereinfachen. Verwenden Sie die geöffneten Dateien als Kontextmanager, damit sie automatisch geschlossen werden:

with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
   reader = csv.reader(infile)
   next(reader, None)  # skip the headers
   writer = csv.writer(outfile)
   for row in reader:
       # process each row
       writer.writerow(row)

# no need to close, the files are closed automatically when you get to this point.

Wenn Sie den Header unverarbeitet in die Ausgabedatei schreiben möchten, ist dies ebenfalls einfach. Übergeben Sie die Ausgabe von next()an writer.writerow():

headers = next(reader, None)  # returns the headers or `None` if the input is empty
if headers:
    writer.writerow(headers)

22
Eine Alternative ist auch auf den Einsatz for row in islice(reader, 1, None)- wenn auch weniger explizit als nextfür die meisten einfach für das Überspringen mehrere Kopfzeilen (oder immer nur bestimmte Stücke etc ...) ist es ganz praktisch Arbeitsplätze „ eine Zeile überspringen“
Jon Clements

Ich würde in Betracht ziehen,try: writer.write(next(reader))... except StopIteration: # handle empty reader
Jon Clements

@ JonClements: Vielleicht. Dies funktioniert gut genug, ohne über try:/ unterrichten zu müssen except:.
Martijn Pieters

1
@ JonClements: Vorteil der expliziten nextIteration ist, dass sie "kostenlos" ist. islicewürde den readerfür immer hinzugefügten (zugegebenermaßen sehr geringen) Overhead zu jeder Iteration einschließen. Das consumeRezept vonitertools kann verwendet werden, um viele Werte schnell zu überspringen, ohne der nachfolgenden Verwendung eine Umhüllung hinzuzufügen, falls die isliceein a startaber nein haben würde end, sodass der Overhead Ihnen nichts bringt.
ShadowRanger

120

Eine andere Möglichkeit, dies zu lösen, besteht darin, die DictReader-Klasse zu verwenden, die die Kopfzeile "überspringt" und damit die benannte Indizierung zulässt.

Geben Sie "foo.csv" wie folgt an:

FirstColumn,SecondColumn
asdf,1234
qwer,5678

Verwenden Sie DictReader wie folgt:

import csv
with open('foo.csv') as f:
    reader = csv.DictReader(f, delimiter=',')
    for row in reader:
        print(row['FirstColumn'])  # Access by column header instead of column number
        print(row['SecondColumn'])

21
Ich denke, dies ist die eigentliche Antwort, da die Frage ein Beispiel für ein XY-Problem zu sein scheint .
Marius Siuram

3
DictReader ist definitiv der richtige Weg
Javier Arias

4
Es ist wichtig zu beachten, dass dies nur funktioniert, wenn Sie den Parameter Feldnamen beim Erstellen des DictReader weglassen. Gemäß der Dokumentation: If the fieldnames parameter is omitted, the values in the first row of the file f will be used as the fieldnames.Siehe docs.python.org/2/library/csv.html
BuvinJ

7

Wenn row=1Sie dies tun , ändert sich nichts, da Sie dies nur mit den Ergebnissen der Schleife überschreiben.

Sie möchten next(reader)eine Zeile überspringen.


Ich habe versucht, es zu ändern, for row in next(reader):aber es gibt mir IndexError: string index out of rangeFehler

Verwenden Sie es vor der for-Schleife: next(reader); for row in reader:....
dlazesz
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.