Als Anfänger in Python stecke ich wieder fest! Ich habe zwei CSV-Dateien wie folgt:

CSV1 (Masterliste)

ID    Name    Code.    Prop
12    SAB     1234     ZXC
12    SAB     1236     ZXC
12    SAB     1233     ZXC
12    SAB     1234     ZXC
11    ASN     1234     ABV
16    HGF     1233     AAA
19    MAB     8765     BCT
19    MAB     8754     BCT

CSV2 (Teilmenge)

ID    Name    Code.    Prop
12    SAB     1234     ZXC
12    SAB     1236     ZXC
12    SAB     1233     ZXC
12    SAB     1234     ZXC
19    MAB     8765     BCT
19    MAB     8754     BCT

Mein Ziel ist es, die Werte in der ersten Spalte der CSVs zu verwenden, um diejenigen zu vergleichen und zu identifizieren, die in CSV2 nicht vorkommen.

BEARBEITEN Im obigen Beispiel sollten also Zeilen mit den IDs 11 und 16 aus CSV1 (Master List) exportiert werden.

Etwas zu beachten. Obwohl die ID eindeutig ist, hat sie in beiden CSV-Dateien mehrere Instanzen (wie in den Beispieldaten aus den obigen CSV-Dateien gezeigt).

Ich habe einige Themen auf dieser Website durchgesehen, z. B. dieser. Was ich versuche zu erreichen, ist das genaue Gegenteil von dem, was hier gefragt wird, aber ich kann die Lösung für diesen Thread nicht verstehen.

Ich habe versucht, einige Ergebnisse zu erzielen, aber ohne Erfolg. Ich habe den folgenden Code angehängt:

import csv

fOpen1=open('C:\Master.csv')
fOpen2=open('C:\Subset.csv')
fOutput1=open('C:\Untagged.csv', 'wb')


master=csv.reader(fOpen1)
subset=csv.reader(fOpen2)
untagged=csv.writer(fOutput1)


count=0

subsetCopy=list()

header1=master.next()
header2=subset.next()

untagged.writerow(header1)


for row2 in subset:
    subsetCopy.append(row2)


for row1 in master:
    for row2 in subsetCopy:
        if row1[0] != row2[0]:
            count=count+1
            untagged.writerow(row1)

print count

Wenn ich das mache, bekomme ich sehr absurde Ergebnisse in der Größenordnung von Millionen (Anzahl). Das Seltsame ist, dass ich genau denselben Code ohne ! = (stattdessen ==) verwendet habe, um ein anderes Ziel zu erreichen, und es hat wie ein Zauber funktioniert. Ich dachte, eine Änderung der Gleichheitsbedingung sollte mir das gegenteilige Ergebnis bringen. Stattdessen wird eine riesige CSV-Datei mit nichts Nützlichem erstellt. Ich habe auch versucht, ein Wörterbuch zu verwenden, aber dann festgestellt, dass es möglicherweise nicht funktioniert, da Datensätze in beiden Dateien doppelt vorhanden sind. Für mich ist es wichtig, alle Instanzen einer bestimmten Zeile in beiden Dateien abzurufen.

Wo gehe ich falsch? Alle Ratschläge / Vorschläge sind willkommen.

0
VGu 17 Aug. 2015 im 08:52

3 Antworten

Beste Antwort

Was Sie falsch machen, ist in dieser Schleife -

for row1 in master:
    for row2 in subsetCopy:
        if row1[0] != row2[0]:
            count=count+1
            untagged.writerow(row1)

Für jede Zeile1 in master wird die ID mit row2 verglichen (unter Verwendung von id), und wenn sie nicht gleich sind, wird diese Zeile1 in "ohne Tags" geschrieben. Dies würde dazu führen, dass row1 viele Male in untagged geschrieben wird, so oft es nicht verwandte Zeilen in subsetCopy gibt, und auf diese Weise überprüfen Sie nicht, ob row1 ID existiert in Teilmenge.

Sie müssten zuerst jede Zeile in subsetCopy durchgehen und sie dann in einem Satz speichern und dann vergleichen, wonach Sie suchen, mit diesem Satz. Beispiel -

import csv

fOpen1=open('C:\Master.csv')
fOpen2=open('C:\Subset.csv')
fOutput1=open('C:\Untagged.csv', 'wb')

master=csv.reader(fOpen1)
subset=csv.reader(fOpen2)
untagged=csv.writer(fOutput1)

count=0

subsetCopy=set()
header1=master.next()
header2=subset.next()
untagged.writerow(header1)

for row2 in subset:
    subsetCopy.add(row2[0])

for row1 in master:
    if row1[0] not in subsetCopy:
            count=count+1
            untagged.writerow(row1)
print count
3
Anand S Kumar 17 Aug. 2015 im 06:01

Zunächst möchten Sie eine set verwenden, die erstellt wird das viel schneller.

Davon abgesehen vergleichen Sie jede Zeile von Datei 1 mit jeder Zeile von Datei 2. Wenn sie nicht übereinstimmen (häufiger Fall), fügen Sie sie der Liste untagged hinzu.

Es ist wichtig zu beachten, dass für jede Datei mit mehr als einer Zeile alle Zeilen Zeilen haben, die nicht übereinstimmen - was dazu führt, dass sie so oft in das Ergebnis geschrieben werden.

Set-Operationen sind in set enthalten und können zu Ihrem eigenen Wohl verwendet werden, insbesondere zu Unterschieden, die wie folgt beschrieben werden:

neue Menge mit Elementen in s, aber nicht in t

set operations table

Hier sind die Änderungen, die vorgenommen werden müssen:

Erstellen Sie einen Satz aus allen Schlüsselelementen in subset und master mit Generatorausdrücke:

subsetSet = set(s[0] for s in subset)
masterSet = set(m[0] for m in master)

Finden Sie den Unterschied der Schlüsselelemente:

untagged_keys = subset - master
print untagged_keys

Verwenden Sie jetzt diese Tasten, wenn Sie vom Master lesen, um nur Zeilen ohne Tags zu lesen:

with open('C:\Master.csv') as f:
    master = csv.reader(f)
    untagged = [m for m in master if m and m[0] in untagged_keys]

print untagged
1
Reut Sharabani 20 Aug. 2015 im 06:07

Selbst wenn Sie im ersten Teil eine Zeile vom Master in einer Teilmenge finden, vergleichen Sie sie weiterhin mit anderen Zeilen und fügen sie ohne Tags hinzu.

Ihre for-Schleife sollte sein:

for row1 in master:
    for row2 in subsetCopy:
        if row1[0] == row2[0]: 
            break
    else:
        count=count+1
        untagged.writerow(row1)

Das heißt: Wenn sich die Zeile an einer beliebigen Stelle in der Teilmenge befindet, ignorieren Sie sie und zählen Sie sie nur, wenn Sie die Teilmenge 2 durchlaufen haben, ohne sie zu finden.

0
Serge Ballesta 17 Aug. 2015 im 06:02