Import csv in python3

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.
Steffi
User
Beiträge: 26
Registriert: Sonntag 4. Oktober 2020, 20:40

Hi, habe den Code jetzt noch einmal mit einer anderen csv-Datei ausprobiert. BlackJack hatte Recht, in der anderen Datei sind keine Daten mehr.
Nun bekomme ich folgende Meldung:
python3 pd.py
Suchbegriff: Amazon
Traceback (most recent call last):
File "pd.py", line 89, in <module>
for row in reader:
File "/usr/lib/python3.6/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe4 in position 3: invalid continuation byte

Ich kann euch leider die csv Datei nicht zur Verfügung stellen, da es mein Kontoauszug ist.
Der Auszug besteht aus 32 Zeilen in der csv-Datei. Was besagt line 321 in der Fehlermeldung???
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@Steffi: dann ist die Datei nicht utf8-kodiert sondern irgendwie anders. Wie, das müßtest Du herausfinden. Wahrscheinlich "cp1252".
Benutzeravatar
__blackjack__
User
Beiträge: 14028
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Steffi: Die besagt das die Ausnahme im Modul `codecs` in Zeile 321 in der Funktion `decode()` ausgelöst wird.

Die Datei ist offenbar nicht UTF-8 kodiert. Also musst Du beim öffnen statt UTF-8 die tatsächliche Kodierung angeben. Die musst Du wissen, oder ”erraten”, oder die Bank hat da irgendwo eine Information zu.

Wenn Du das in einem Texteditor öffnest und da die Umlaute und andere Sonderzeichen (€-Zeichen ist hier vielleicht auch enthalten und wichtig) richtig angezeigt werden, dann schau mal wo Du die Information findest was der Editor da als Zeichenkodierung verwendet für das laden/speichern dieser Datei.

Falls die Sonderzeichen nicht richtig angezeigt werden, kannst Du schauen wie man in dem Editor die Datei in einer anderen Kodierung laden kann und probieren ob beispielsweise ISO-8859-15 funktioniert.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
lexx
User
Beiträge: 19
Registriert: Sonntag 23. Dezember 2018, 14:15

Tag auch,

ich meine mit pathlib.Path(Dateiname).open() kann man sich das encoding anzeigen lassen.
Wäre das Thema nicht was für Panda ?!
Benutzeravatar
__blackjack__
User
Beiträge: 14028
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@lexx: Damit kann man sich die Kodierung genau so wenig anzeigen lassen wie mit `open()` aber genau wie `open()` sollte/muss man die richtige Kodierung dort angeben wenn man die Datei im Textmodus öffnet.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
lexx
User
Beiträge: 19
Registriert: Sonntag 23. Dezember 2018, 14:15

Hatte es mal so gelesen in den Weiten des Internet und es hat funktioniert.
<_io.TextIOWrapper name='C:\\Users\\user\\Desktop\\Datei.csv' mode='r' encoding='cp1252'>
Benutzeravatar
__blackjack__
User
Beiträge: 14028
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@lexx: Was hat funktioniert? Das Du eines der beiden `open()` verwendest und das die Kodierung verwendet die auf der Plattform eingestellt ist — egal ob das nun die tatsächliche Kodierung der Textdatei ist? Ja das funktioniert. Halt nur solange die Kodierung zufällig tatsächlich mit der Kodierung die da angenommen wird übereinstimmt.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
lexx
User
Beiträge: 19
Registriert: Sonntag 23. Dezember 2018, 14:15

Was wäre denn die richtige Methode, um das zu erraten?
Hatte es wie gesagt mal so gefunden, weil ich auch mal Probleme hatte.
Benutzeravatar
__blackjack__
User
Beiträge: 14028
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@lexx: Man muss sich die Datei mit verschiedenen Kodierungen anschauen und wenn alles richtig aussieht, hoffen dass es das auch ist. CP1252 ist bei uns (Westeuropa) die übliche Kodierung für grafische Windowsanwendungen. In der Windowseingabeaufforderung ist glaube ich bei uns immer noch CP850 Voreinstellung, also das was man bei DOS in Westeuropa eingestellt hat. PowerShell verwendet AFAIK UTF-8 oder UTF-16. Linux-Systeme in der Regel UTF-8 und MacOS AFAIK auch UTF-8.

Als Programmierer, wenn man selber Daten erzeugt und frei entscheiden kann, würde ich UTF-8 empfehlen, weil man damit alles kodieren kann was Unicode an Zeichen bietet, und es bei überwiegend ASCII-Zeichen a) kompakt ist, und man b) das ganze auch bei einer falschen 8-Bit-Kodierung die ASCII als gemeinsame Schnittmenge hat, trotzdem noch halbwegs entziffern kann. Und Werkzeuge die mit ASCII oder den üblichen 8-Bit-Kodierungen klar kommen und denen der Inhalt nicht ganz so wichtig ist, trotzdem mit den Dateien arbeiten können und oft oder fast immer das richtige machen.

UTF-8 ist beispielsweise auch die Standardkodierung für Python-Quelltexte und XML-Dateien. Und auch wenn es nicht spezifiziert ist, kann man das auch von JSON-Dateien mit ziemlicher Sicherheit erwarten.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Steffi
User
Beiträge: 26
Registriert: Sonntag 4. Oktober 2020, 20:40

Hi, ich habe es mal mit CP1252 versucht und hatte Glück. Nun wird mir endlich ein Ergebnis angezeigt, aber es werden alle Kontoumsätze angezeigt und nicht nur die, welche den Suchbegriff beinhalten.

Code: Alles auswählen

import csv
search = input("Suchbegriff: ")
with open("04_20.csv", encoding="cp1252", newline="")as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        if search in row:
            print("Gefunden n")
        print(row[0])
Habt Ihr noch Tipps???
Benutzeravatar
__blackjack__
User
Beiträge: 14028
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Steffi: Natürlich werden alle angezeigt. Das steht das so was von offensichtlichem im Code das von jedem Datensatz das erste Feld angezeigt wird. Warum hättest Du da jetzt etwas anderes erwartet?
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Steffi
User
Beiträge: 26
Registriert: Sonntag 4. Oktober 2020, 20:40

Na ja, weil ich gerne eine code wollte, der die Zeilen ausgibt, in dem mein Suchbegriff steht.
Hatte gedacht, dass ich mit diesem Code auf dem richtigen Weg bin.
Wie schreibe ich den Code den jetzt um, damit die Zeilen ausgegeben werden, die meinen Suchbegriff beinhalten?
Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

Es nützt ja nichts, wenn du Code schreibst, den du nicht verstehst.
Schreib doch mal für die letzten 3 Zeilen auf, was sie tun und wann sie das tun.
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du musst halt abbrechen. Das geschieht zB durch break oder return innerhalb der betreffenden Verzweigung. Ein print() verlässt die Schleife nicht, dh es wird (und das hast du anscheinend nicht erwartet) auch der Code nach der Verzweigung ausgeführt.
Steffi
User
Beiträge: 26
Registriert: Sonntag 4. Oktober 2020, 20:40

wird durch break nicht abgebrochen, wenn der Suchbegriff gefunden wurde?? Ich möchte ja, dass alle Zeilen durchsucht werden und dann sollen alle Zeilen mit dem Suchbegriff als Ergebnis angezeigt werden. Ich habe z.B. einen Kontoauszug in csv-Datei mit 32 Zeilen. Ich suche nach dem Begriff Amazon und dann soll mir der 1.4.20 Amazon... und der Betrag angezeigt werden, z.B.
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

In dem Fall kann man eine List Comprehension benutzen:

Code: Alles auswählen

result = [row for row in reader if suchbegriff in row]
Im Ergebnis laden dann nur die Datensätze, für die suchbegriff in row zutrifft.
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: ich glaube, Du bist schon wieder einen Schritt zuweit.
Zuerst geht es darum, wann welches `print` ausgeführt wird.
Wenn das klar ist, kann man später immer noch statt `print` eine Datenstruktur zu benutzen.
Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

@Steffi: Ich schrieb es bereits weiter oben und würde es noch um eine Zeile erweitern:
Bitte schreibe doch mal, was du denkst, was und wann (im Sinne von unter welche Bedingung) die letzten 4 Zeilen machen.
Und zwar Zeile für Zeile, nicht in einem Fließtext.
Das hilft dabei, dass es am Ende bei dir Klick macht.

Code: Alles auswählen

    for row in reader:   # Diese Zeile tut:
        if search in row:    # Diese Zeile tut:
            print("Gefunden n")    # Diese Zeile tut:
        print(row[0])    # Diese Zeile tut:
benpython
User
Beiträge: 8
Registriert: Sonntag 10. Mai 2020, 12:24

Steffi hat geschrieben: Samstag 10. Oktober 2020, 14:52 Hi, ich habe es mal mit CP1252 versucht und hatte Glück. Nun wird mir endlich ein Ergebnis angezeigt, aber es werden alle Kontoumsätze angezeigt und nicht nur die, welche den Suchbegriff beinhalten.

Code: Alles auswählen

import csv
search = input("Suchbegriff: ")
with open("04_20.csv", encoding="cp1252", newline="")as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        if search in row:
            print("Gefunden n")
        print(row[0])
Habt Ihr noch Tipps???
Du kannst regex benutzen um im Text einer Zeile nach einem Begriff zu suchen. Genauso kannst du dann wenn du was findest weitere Infos z.B. Datum, Betrag etc. suchen.
Unter https://regex101.com/ kannst du dein Text einfügen und regex patterns erstellen und testen.
Hier ein Beispiel wie ich mir das vorstelle:

Code: Alles auswählen

import os
import re
import csv

pattern = re.compile(r'(amazon)')
with open(os.path.join(os.path.expanduser('~/Desktop/'),'Abrechnung.csv'),encoding='iso-8859-1') as csvdatei: #cp1252
    csv_reader_object = csv.reader(csvdatei, delimiter=';')
    idx=0
    for row in csv_reader_object:
        idx=+1
        for column in range(0,len(row)):
            if re.match(pattern, str(row[column]).lower()):
                    found = re.match(pattern, str(row[column]).lower())
                    found = found.group(1)
                    print(f'Suchwort "{found}" gefunden in Zeile {idx}, Spalte {column}')
            else:
                found = None
Kann man mit Sicherheit noch Refactoring betreiben an dem Code. Ist nur ein Beispiel.

Falls du eine OCR brauchst würde ich dir Tesseract empfehlen ( https://github.com/tesseract-ocr/tesseract/ ). Bin mir nicht sicher ob er auch PDF in Text umwandelt aber mit Bilder funktioniert es hervorragend.
Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

@benpython: Das ist aber schon ein bisschen mit Kanonen auf Spatzen wenn man regex auspackt um festzustellen, dass sich eine feste Zeichenkette in einer anderen Zeichenkette befindet.
Antworten