csv Datei auslesen und Vergleich

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
lostin
User
Beiträge: 7
Registriert: Donnerstag 9. September 2010, 05:01

Hallo,

ich versuche aus einer csv Datei eine Nummer auszulesen(Art.-Nr.) und diese mit den Nummern einer zweiten csv Datei zu vergleichen.
Kommt also Artikelnr aus csv1 auch in csv2 vor. Wenn die Nummer nicht vorkommt, möchte ich den Datensatz/String/wie auch immmer in eine
eigene Datei schreiben. An sich nicht so schwer, bin allerdin neu in python.In dem unteren Beispiel wird an ansich gar nichts gefunden
obwohl ich genau weiss das einige Sätze ausgegeben/gefunden werden sollten.
Vielleicht kann ja jemand einen Tipp geben und kann helfen.

Hier das was ich bisher gemacht habe:

Code: Alles auswählen

import csv, sys, os

output = csv.writer(open("testoutput.csv", "wb"), delimiter=";") 
fileenglisch = csv.reader(open("englisch.csv", "rb"), delimiter=";")
fileshop = csv.reader(open("shop.csv", "rb"), delimiter=";")
count = 0

for englischline in fileenglisch:
    for shopline in fileshop:
        #print 'Shop:' + shopline[1] + ' Englisch: ' + englischline[1]
        if englischline[1] != shopline[1]:
            output.writerow(englischline)
            count +=1
 
print 'Anzahl: ' + str(count)
print "fertich"

Gruß
lostin
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Wenn bei deinen zur zeit auskommentieren print anweisungen (und der count) etwas gefunden und ausgegeben wird, kann es sich nur um etwas output.writerow(englischline) handeln. was sagt denn print englischline.

Sonst:
Wird das file wieder geschlossen?

Code: Alles auswählen

csvwritefile = open("testoutput.csv", "wb")
output = csv.writer(csvwritefile, delimiter=";") 
output.writerow(...)
...
csvwritefile.close()
lostin
User
Beiträge: 7
Registriert: Donnerstag 9. September 2010, 05:01

Bei der auskommentierten Zeile erscheint einmal die eingelesene Artikelnummer aus shopline und immer nur die erste Artikelnummer aus englischline. *mhhh*, es wird anscheinend nur ein Durchlauf lang verglichen. Alles Shopzeilen gegen die erste Zeile der englischline :K

Dabei sollte doch, nachdem die erste (englischline)Artikelnummer mit alles Zeilen der shopdatei verglichen wurde, die nächste englischline eingelesen werden um wiederum mit alles shopzeilen verglichen zu werden.

Ansonsten wird das File nicht geschlossen. Danke für den Hinweis!
Ich habe gerade das Gefühl, ich sehe den Wald vor lauter Bäumen nicht mehr...
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Dateien sollte man grundsätzlich mit dem with-Statement öffnen, dann werden sie auch im Fehlerfall vernünftig geschlossen.
Soweit ich das verstehe, wird auch für jede Zeile in "fileenglisch" (Namen sind lesbarer mit _ zur Trennung von Wortteilen, also z.B. file_english) jede Zeile der Datei "fileshop" nochmal eingelesen. Ist eventuell nicht das Effizienteste. ;)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

lostin hat geschrieben:Bei der auskommentierten Zeile erscheint einmal die eingelesene Artikelnummer aus shopline und immer nur die erste Artikelnummer aus englischline. *mhhh*, es wird anscheinend nur ein Durchlauf lang verglichen. Alles Shopzeilen gegen die erste Zeile der englischline :K
Das Programm nimmt die erste Zeile der Datei englisch.csv und rennt dann einmal komplett durch die Datei shop.csv. Wenn die zweite Zeile der Datei englisch.csv abgearbeitet wird, dann bist du in der shop.csv durch den ersten Durchlauf schon am Ende angelangt und kannst dort nichts neues mehr holen. Das fängt nicht automatisch wieder von vorne an.
BlackJack

@lostin: Das Vorgehen an sich ist sehr ineffizient weil für jede Zeile der einen Datei die Andere komplett durchlaufen wird. Besser wäre es eine der beiden Dateien am Anfang in den Speicher zu lesen. Da bietet sich die "shop"-Datei an, weil von der anscheinend ja nur das jeweils zweite Element jedes Datensatzes benötigt wird. Diese kann man in ein `set()` stecken um effizient prüfen zu können, ob der Wert enthalten ist.

Deine ``if``-Bedingung würde bei der doppelt verschachtelten Schleife auch zu *sehr* vielen und *doppelten* Ausgabezeilen führen.

Hier mal ein Vorschlag (ungetestet):

Code: Alles auswählen

import csv

ARTICLE_NUMBER_INDEX = 1


def main():
    with open('shop.csv', 'rb') as shop_file:
        reader = csv.reader(shop_file), delimiter=';')
        shop_article_numbers = set(row[ARTICLE_NUMBER_INDEX] for row in reader)
    
    count = 0
    with open('english.csv', 'rb') as english_file:
        with open('testoutput.csv', 'wb') as out_file:
            reader = csv.reader(english_file, delimiter=';')
            writer = csv.writer(out_file, delimiter=';')
            for row in reader:
                if row[ARTICLE_NUMBER_INDEX] not in shop_article_numbers:
                    writer.writerow(row)
                    count += 1
    print 'Anzahl:', count


if __name__ == '__main__':
    main()
lostin
User
Beiträge: 7
Registriert: Donnerstag 9. September 2010, 05:01

mkesper hat geschrieben:Dateien sollte man grundsätzlich mit dem with-Statement öffnen, dann werden sie auch im Fehlerfall vernünftig geschlossen.
Soweit ich das verstehe, wird auch für jede Zeile in "fileenglisch" (Namen sind lesbarer mit _ zur Trennung von Wortteilen, also z.B. file_english) jede Zeile der Datei "fileshop" nochmal eingelesen. Ist eventuell nicht das Effizienteste. ;)
Danke für den Hinweis. Meine python Version(2.5.1) unterstützte das with statement (noch) nicht :-/
Habe mir jetzt allerdings 2.7 installiert :)
lostin
User
Beiträge: 7
Registriert: Donnerstag 9. September 2010, 05:01

/me hat geschrieben: Das Programm nimmt die erste Zeile der Datei englisch.csv und rennt dann einmal komplett durch die Datei shop.csv. Wenn die zweite Zeile der Datei englisch.csv abgearbeitet wird, dann bist du in der shop.csv durch den ersten Durchlauf schon am Ende angelangt und kannst dort nichts neues mehr holen. Das fängt nicht automatisch wieder von vorne an.
Genau das hat mich total veerwirrt! KAnn man den Dateizeiger denn nicht wieder an den Anfang der Datei setzten...
Naja, es gibt ja auch andere Lösungen, wie mkesper auch bemerkte ;)
lostin
User
Beiträge: 7
Registriert: Donnerstag 9. September 2010, 05:01

BlackJack hat geschrieben:@lostin: Das Vorgehen an sich ist sehr ineffizient weil für jede Zeile der einen Datei die Andere komplett durchlaufen wird. Besser wäre es eine der beiden Dateien am Anfang in den Speicher zu lesen. Da bietet sich die "shop"-Datei an, weil von der anscheinend ja nur das jeweils zweite Element jedes Datensatzes benötigt wird. Diese kann man in ein `set()` stecken um effizient prüfen zu können, ob der Wert enthalten ist.

Deine ``if``-Bedingung würde bei der doppelt verschachtelten Schleife auch zu *sehr* vielen und *doppelten* Ausgabezeilen führen.
Dear BlackJack,

ein dickes THX! Dein ungetesteter Code war fast perfekt, Ich habe das ganze ein weing angepasst und es läuft. Noch wichtiger die "Nummer" mit dem einlesen in den Speicher und dann mit not in vergleichen, klasse, wieder was dazugelernt *notiertfürsnächstemal* !

Neben Deiner Lösung hast Du natürlich auch recht mit der Aussage das vieles doppelt und das sehr häufig auftreten würde bei meiner Lösung.

OK, damit hat sich das nachfragen hier in der netten Community gelohnt. Ein großes DANKE an alle die sich Zeit für ein Posting genommen haben!
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

@Lostin
bei mir laeuft die Loesung von BlackJack nicht. Mich wuerd mal interessieren, wie deine Loesung aussieht.
Etwas sallop und flappsig koennte man fragen: was will uns der Kuenstler eigentlich sagen?
dazu muessten auch deine csv-dateien hochgeladen werden.
Wie das geht, hat uns neulich DaMutz geschrieben.
Ich arbeite (auf diesem Lappy) noch mit Python2.5 daher werden with-Statements nicht ausgefuehrt.
Die Loesung ist deshalb interessant, weil sich immer mehr csv-files durchsetzen. Wir nehmen diesen File-typ fuer Messwerte einzulesen und fuer Excel-Dateien.
Es gibt mittlerweile interessante Microcontroller-Loesungen, wo Messreihen schon als csv-files erzeugt werden.
mein Programm ist hier:
http://www.python-forum.de/pastebin.php?mode=view&s=62
Die logdatei steht hier:
http://www.python-forum.de/pastebin.php?mode=view&s=63

wird so erzeugt:2.py &> 2.err
Unter Unix!
Wie das unter Win geht: ???


In der csv-Bib(von Python) kann man (als Modifier) auch excel-files einlesen.

Guude!
Fritz
BlackJack

Python 2.5 kennt die ``with``-Anweisung wenn man als ersten Import ein ``from __future__ import with_statement`` verwendet.
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

@BlackJack
will nicht unfreundlich werden, aber mach Dir mal die Muehe, in die pastebin zu schauen.
Jetzt- wo ich die pastbin beherrsche!!!- werd ich da oefter was reinschreiben.
habe 1 Beispiel zur csv-datei ausgearbeitet und werde das in einem Beitrag mal zur Diskussion stellen.
Die csv-dateien sind enorm wichtig, man muss aber wissen, was da passiert und welche flexiblen Moeglichkeiten Python bietet.
Guude!
Fritz
:idea:
BlackJack

@3ff: Das hat nichts mit ``with`` zu tun -- die Anweisungen werden bei Dir sehr wohl ausgeführt. Du hast in Deiner 'shop.csv' halt keine zweite Spalte, oder zumindest nicht in jeder Zeile. Da kann mein Quelltext ja nix dafür.
Antworten