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.
3 Antworten
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
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
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
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.
Verwandte Fragen
Verknüpfte Fragen
Neue Fragen
python
Python ist eine dynamisch typisierte Mehrzweck-Programmiersprache mit mehreren Paradigmen. Es wurde entwickelt, um schnell zu lernen, zu verstehen, zu verwenden und eine saubere und einheitliche Syntax durchzusetzen. Bitte beachten Sie, dass Python 2 ab dem 01.01.2020 offiziell nicht mehr unterstützt wird. Fügen Sie für versionenspezifische Python-Fragen das Tag [python-2.7] oder [python-3.x] hinzu. Wenn Sie eine Python-Variante (z. B. Jython, PyPy) oder eine Bibliothek (z. B. Pandas und NumPy) verwenden, fügen Sie diese bitte in die Tags ein.