CSV-Modul Error; Ansprache einzelner Elemente

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
PhantomWorks
User
Beiträge: 18
Registriert: Samstag 25. April 2009, 11:11

Hallo zusammen!

Ich bin gerade dabei eine große CSV Datei (60MB; 1.050.000 Zeilen, 1 Spalte) mit dem csv Modul zu importieren, doch ich erhalte stets folgenden Error: "_csv.Error: field larger than field limit"

Anscheined ist das File zu groß für das Modul. Wie kann ich dies umgehen?

Wenn mir dann mit Eurer Hilfe einmal der Import geglückt ist, ist die nächste Frage wie ich einzelne Elemente gezielt ansprechen kann. Diese ein Spalte der CSV enthält drei Dinge: Wert1, Wert2, Wert3
MEine Idee war nun aus diesen ein Dictionary zu erzeugen mit Wert1 als Schlüssel und den anderen beiden als Werten. Da die 3 Elemente aber weder (wie in meinen bisherigen Fällen) Spaltenbezeichner haben (Stehen alle in einer Spalte) und nur durch Komma voneinander getrennt sind, frage ich mich wie ich daraus ein Dict nach bekanntem Muster erstellen kann und ich im Anschluss daran noch einzelne Werte gezielt ansprechen kann.

Bisheriges Vorgehen war immer folgendermaßen:

Code: Alles auswählen

content = csv.DictReader(open(source_dir + os.sep + 'Test.csv', 'r'), delimiter = ';', quotechar = '|')
data = {}
for line in content:
    data[line ["BezeichnerSpalte1"]] = line
Das Ansprechen der einzelnen Elemente erfolgte so:

Code: Alles auswählen

Wert2 = util.escape(data[BezeichnerSpalte1]["BezeichnerSpalte2"])
Bei diesem Fall jedoch, ohne Spaltenbezeichner und ohne dass die einzelnen Werte in eigenen Spalten stehen, sondern alles durch Komma getrennt in einer Einzigen, bin ich ratlos.


Danke schonmal für Eure Tipps und Hilfestellungen!

Viele Grüße,
Sepp
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Kannst du mal einen Ausschnitt aus deiner csv-Datei posten?
"...Eine Spalte" und "enthält drei Werte" ergibt nämlich keinen Sinn.
Außerdem gibts csv.reader() - das funktioniert auch ohne Feldnamen.

hth, Jörg

ps.: In der Python-Dokumentation gibt's auch Beispiele zum csv-Modul
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

hi,

hatte hier noch einen test zu csv rumliegen.
grade mit nem file > 1M zeilen probiert, kein problem.


Code: Alles auswählen

import csv

try: reader = csv.reader(open("test.csv", "r"))
except IOError, e: 
    print "IOError: %s : '%s'" % (e.strerror, e.filename)
    sys.exit(e.errno)
    
for row in reader:
    print row
PhantomWorks
User
Beiträge: 18
Registriert: Samstag 25. April 2009, 11:11

Danke für Deinen Tipp Dill! Der Import funktioniert jetzt und jede Zeile der csv ist jetzt eine Liste.

Es ergibt sich nun folgendes Problem:
Manche der erstellten Listen enthält nun nur 3 Elemente (d.h. row[3] fehlt), andere habe 4 Elemente. Lasse ich das Script nun über die Datei laufen, gibt er mir einen IndexError aus "List index out of range", da ich versuche bei den Listen, die keine row[3] enhalten ein Element anzusprechen das nicht existiert.

Habe versucht es mit einer Ausnahme zu lösen, doch das will irgendwie nicht so ganz funktionieren. Wo liegt in folgendem Code der Fehler begraben?

Code: Alles auswählen

for row in reader:
    w = row[0]
    x = row[1]
    y = row[2]
    z = row[3] # Problem: bereits bei dieser Line bekomme ich bei der     Ausführung des Scripts den o.g. IndexError
    if (z == ""):
        try:
            row[3]
        except IndexError:
            print "Kein Wert verfügbar!"
Mein Ziel ist es, eine nicht existierendes 4. Listenelement einfach zu ignorieren.

Viele Grüße,
Sepp
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Der Fehler ist, dass du nicht den ersten `IndexError` abfängst sondern den 2. und den 2. unnötigerweise konstruierst.
Aber ich seh da ein ganz andres Problem:
Wenn du die Werte an - nichtssagende Namen - zuweist, ensteht beim Zugriff auf `z` ein NameError, bzw greift noch auf das `z` des vorhergehenden Durchlaufs zu.

Arbeite lieber direkt auf der Dateistruktur des Readers und fang die `IndexError` da auf, wo sie entstehen.

Edit: Mir fällt grad auf, dass die sowieso schon ein `NameError` entgegen fliegen kann bei deinem - nicht funktionsfähigen - Code. Auch ist `z` nicht notwendigerweise ein leerer String. Meine Vorschläge gelten aber immernoch ;)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du bekommst schon in der Zeile den Fehler, da du an dieser Stelle bereits versuchst das vierte Element an z zu binden. Das try bedeutet nicht, dass irgend etwas getestet wird, sondern dass ein Fehler ggf. behandelt wird. Du müsstest es also etwa so lösen:

Code: Alles auswählen

for row in reader:
    w = row[0]
    x = row[1]
    y = row[2]

    try:
        z = row[3]
    except IndexError:
        z = ""
Was genau im Falle eines Fehler passieren soll müsstest du deinen Wünschen nach im except-Block anpassen.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

überleg dir mal ob es möglich und dann nicht evtl besser ist für vernünftige eingangsdaten zu sorgen.

statt einem solchen csv:

Code: Alles auswählen

1,2,3
1,2
1,2,3
solltest du besser mit so etwas arbeiten:

Code: Alles auswählen

1,2,3
1,2,
1,2,3
PhantomWorks
User
Beiträge: 18
Registriert: Samstag 25. April 2009, 11:11

Hallo zusammen!

Erst einmal vielen Dank für Eure Tipps und Lösungsvorschläge. Es hat inzwischen funktioniert und ich konnte die gewünschte Ausgabedatei erzeugen.

Ein super Forum!

Viele Grüße,
Sepp
Antworten