2016-06-23 13 views
-2

Ich habe ein wirklich seltsames Problem. Ich habe drei Dateien, die eine Spalte mit Zahlen enthalten. Ich brauche NUR eindeutige Werte von der ersten Datei, die nicht in der zweiten und dritten Datei vorhanden sind.Zwei Dateien Vergleich

Ich habe versucht, Python wie:

for e in firstfile: 
    if e not in secondfile: 
     resultfile.append(e) 
return resultfile 

Und gleiche gilt für dritte Datei.

Ich habe versucht, uniq, sortieren, diff, einige awk-Skripte und comm in Linux-Shell wie hier: Fast way of finding lines in one file that are not in another?

Aber das einzige Ergebnis, das ich jedes Mal bekommen, ist die gleiche Menge an LINIEN WIE IM EHEMALIGEN FIRST Datei wurde. Ich verstehe es überhaupt nicht!

Vielleicht habe ich etwas verpasst? Vielleicht ist es etwas mit einem Format? Allerdings habe ich es oft überprüft. Hier sind die Dateien: http://dropmefiles.com/BaKGj

P.S. Später dachte ich, dass es überhaupt keine eindeutigen Zeilen gibt, aber ich habe es manuell überprüft, einige Zahlen in der ersten Datei sind einzigartig.

P.P.S. Das Format der Dateien ist wie folgt:

380500100000 
380500100001 
380500100002 
380500100003 
380500100004  
380500100005 
380500100008 
380500100020 
380500100022 
380500100050  
380500100070 
380500100080 
+0

Wenn es nur eine Spalte von Zahlen ist, können Sie auch 20 von eacg einschließen, damit wir verstehen, welche Daten Sie verwenden. Putting sie dropmefiles hilft Menschen in der Zukunft nicht, wie die Datei in 7 Tagen entfernt wird. Ich würde auch die erste Datei laden und dann alles entfernen, das von der zweiten und dritten Datei geladen wird, wenn es in der ersten Datei existiert. – IvanD

+0

Sicher, es ist eine nette Notiz. Bist du ein russophon? – tiredsys

Antwort

2

Was ist falsch

Und gleiche gilt für dritte Datei

Wenn Sie wirklich das gleiche gilt für die dritte Datei tun, dh den ursprünglichen Inhalt der ersten Datei zu vergleichen mit der dritte, du kannst Duplikate von Elementen einführen, die nicht in der zweiten Datei waren, aber in der dritten. Zum Beispiel:

 
file 1: 
1 
2 
3 

file 2: 
1 

file 3: 
2 

Nach Dateiverarbeitung 2, würde resultfile enthalten 2 und 3 dann nach 3-Datei der Verarbeitung würde resultfile enthalten 2 und 3 (von dem ersten Durchlauf) zuzüglich 1 und 3, das heißt 2, 3, 1, 3. Allerdings sollte das Ergebnis nur 3.

Es aus dem Code nicht klar ist, ob Sie tatsächlich die Ausgabe von jedem Lauf auf die Datei zu schreibenresultfile. Wenn dies der Fall ist, sollten Sie es als Eingabe für den zweiten und die folgenden Läufe verwenden. Verarbeiten Sie die erste Datei nicht erneut.


Ein besserer Weg, es zu beheben

Wenn Sie Sie set.difference() wie dies nicht die Reihenfolge der Zeilen aus der ersten Datei beibehalten müssen verwenden könnte:

with open('file1') as f1, open('file2') as f2, open('file3') as f3: 
    unique_f1 = set(f1).difference(f2, f3) 

Beachten Sie, dass Dies schließt alle Leerzeichen (einschließlich Zeilenvorschubzeichen) ein, die in den Dateien vorhanden sind.Wenn Sie mit Python 2 dann gegebenenfalls für eine bessere Effizienz, importieren itertools.imap und es zu verwenden, statt map()

from itertools import chain 

with open('file1') as f1, open('file2') as f2, open('file3') as f3: 
    unique_f1 = set(map(str.strip, f1)).difference(map(str.strip, chain(f2, f3))) 

Die oben geht davon aus Python 3.: Wenn Sie führende und nachfolgende Leerzeichen aus jeder Zeile ignorieren wollte.

Oder Sie möchten die Daten als numerische behandeln (I float hier übernehmen werde, aber Sie können int stattdessen verwenden):

from itertools import chain 

with open('file1') as f1, open('file2') as f2, open('file3') as f3: 
    unique_f1 = set(map(float, f1)).difference(map(float, chain(f2, f3))) 
+0

Ich sehe Ihren Punkt, aber mein Code ist komplizierter als das. Ich wollte einfach nicht alles einfügen, also machte ich es ein bisschen leichter zu verstehen. Ursprünglich habe ich CSV-Dateien geöffnet, daraus Listen erstellt, dann jedes Element der ersten Liste iteriert und in der Ergebnisliste gespeichert. Dann nahm ich die Ergebnisliste der ersten Iteration und machte dasselbe für die dritte Liste (Datei), das Ergebnis wurde in einer anderen Liste gespeichert, die später in die vierte (resultierende) CSV-Datei geschrieben wurde. – tiredsys

0

Der einfachste Weg wäre, jede Datei in ein set, zu lesen und dann Python (sehr effizient) Set-Operationen nutzt den Vergleich zu tun.

file1 = set() 
file2 = set() 

for element in firstfile: 
    file1.add(element) 

for element in secondfile: 
    file2.add(element) 

unique = file1 - file2 
+0

Ich versuchte Sätze wie folgt: 1. Geöffnete csv-Dateien in Python von CSV-Modul. 2. Extrahiert alle Daten aus diesen Dateien und übertrug sie in Listen. 3. Sätze aus diesen Listen erstellt. 4. Die von Ihnen vorgeschlagene Konstruktion wurde versucht (unique = file1 - file2). Hat es den gleichen Effekt oder ich sollte Ihre Option versuchen? – tiredsys

+0

Das wird gut funktionieren. Ich habe gerade diese (ineffiziente) Konstruktion verwendet, weil ich nicht sicher war, wie Sie die Dateien in den Speicher lesen. – Batman

0

Es ist wahrscheinlich das Problem sein könnte, dass first.csv ist streng ASCII-Text, während second.csv und third.csv ASCII-Text sind, mit CRLF-Zeilenabschlusszeichen. Ich würde vorschlagen, dass Sie sie in das gleiche Format ändern (ASCII-Text würde wahrscheinlich am besten funktionieren).

$ file first.csv 
first.csv: ASCII text 

$ file second.csv 
second.csv: ASCII text, with CRLF line terminators 

$ file third.csv 
third.csv: ASCII text, with CRLF line terminators