Zwei Exceldateinen vergleichen

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.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Saar-Pfalz666: Kommt ein bisschen darauf an was „vergleichen“ genau bedeutet. Wenn man wissen möchte ob die genau gleich sind, bis auf die Reihenfolge, dann kann man einfach beide Seiten des Vergleichs in die gleiche Reihenfolge bringen, also sortieren, und dann vergleichen. Wenn man wissen möchte wie die sich unterscheiden, sind Mengenoperationen ein Werkzeug.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Saar-Pfalz666
User
Beiträge: 16
Registriert: Freitag 7. September 2018, 14:00

@_blackjack_ hab’s mir jetzt gerade nochmal angesehen. In der einen Datei sind mehr Zeilen als in der anderen.
Ich möchte nun die Zeilen finden die es nur in Datei1 gibt.
Dabei reicht es mir auch nur einzelne Spalten zu vergleichen, da es hier auch irrelevante Werte gibt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann packst Du die relevanten Spalten von Datei2 oder 3 am besten in ein Set, damit der Vergleich einfach wird und gehst alle Zeilen in Datei1 durch, und vergleichst, ob sie im Set sind.
Saar-Pfalz666
User
Beiträge: 16
Registriert: Freitag 7. September 2018, 14:00

import pandas as pd

import numpy as np

df1 = pd.read_excel('data.xls', 'Sheet1', na_values=['NA'], dtype=object)
df2 = pd.read_excel('hcc.xls', 'Sheet1', na_values=['NA'], dtype=object)
df3 = pd.read_excel('hck.xls', 'Sheet1', na_values=['NA'], dtype=object)

df4 = df2.append(df3, ignore_index=True)

df1.sort_values(by=['TTNR'])

df4.sort_values(by=['TTNR'])

df6 = df1.values

df7 = df4.values

df8 = set(df1.TTNR), set(df1.Abgänge), set(df1.Startbestand), set(df1.Zugänge), set(df1.Endbestand), set(df1.DLZ), set(df1.Durchschnittsbestand), set(df1.SummeBestand), set(df1.SummeAbgang), set(df1.Stufendurchschnitt), set(df1.Disponent)

df9 = set(df4.TTNR), set(df4.Abgänge), set(df4.Startbestand), set(df4.Zugänge), set(df4.Endbestand), set(df4.Durchlaufzeit), set(df4.Durchschnittsbestand), set(df4.SummeBestand), set(df4.SummeAbgang), set(df4.Stufendurchschnitt), set(df4.Disponent)

df8^df9

Da stecke ich jetzt fest und bekomme immer wieder eine Fehlermeldung (TypeError: unsupported operand type(s) for ^: 'tuple' and 'tuple'). Hab schon etliches versucht mittlerweile und mich durch unzählige Beiträge gelesen.

Das zwischen drin verwirrt vielleicht (df.values) und war nur ein Test ob es mit arrys funktioniert.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte gewöhn dir mal sofort ab, Variablen durchzunummerieren. Das kann niemand anderes lesen und verstehen. Und niemand anderes bist auch du in 2 Wochen.

Die df8 und df9 sind Tupel. Alles was dem Muster

Code: Alles auswählen

x  = a, b, c
folgt, ist ein Tupel.

Ich vermute mal, das du statt einem Tupel mit Mengen eine Menge von Tupeln willst. Also

Code: Alles auswählen

df3682927263 = set(df127183819101.values)
sollte eigentlich klappen.
Saar-Pfalz666
User
Beiträge: 16
Registriert: Freitag 7. September 2018, 14:00

Code: Alles auswählen

df_all = set(df1.values)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-35-872c92222221> in <module>()
----> 1 dfall = set(df1.values)

TypeError: unhashable type: 'numpy.ndarray'

Ich hab es jetzt so geschrieben wenn ich deine Antwort richtig gedeutet habe. Leider kam aber hier auch eine Fehlermeldung.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hrmpf. Auf meinem iPad kann ich leider kein Pandas. Ich hatte gehofft das geht. So musst du auf einen der anderen warten, oder versuchen selbst rauszufinden wie man eine Liste von Zeilen erhält.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@__deets__: `values` ist ja eine ”Liste” von Zeilen. Jede Zeile ist wieder ein Array, aber eben ein veränderbares, darum nicht hashbar, und darum so nicht direkt in ein `set()` zu stecken. Ist nicht anders als wenn man eine Liste von Listen hätte. Ein ``set(map(tuple, values))`` sollte gehen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Saar-Pfalz666
User
Beiträge: 16
Registriert: Freitag 7. September 2018, 14:00

Vielen Dank, mit einer vereinfachen Test-Datei hat es funktioniert.
Ich beginne jetzt auch mein Problem zu verstehen :)
Sobald eine Zelle in der Spalte zwischen beiden Datensätzen unterschiedlich ist bekomme ich die ganze Zeile als „False“ ausgegeben.

Also muss ich wohl weiter vorne zuerst nochmal ansetzen damit ich beide Tabellen gleich bekomme.
Kann ich nur ausgewählte Spalten in ein Array packen? Ich weiß ja das ich eine Spalte nur in der einen Datei hab.
So werde ich immer alle Datensätze „false“ haben.

Vielen Dank nochmal für euere Unterstützung
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Saar-Pfalz666: Ja man kann einen neuen Dataframe aus Spalten des alten erstellen. Eventuell lohnt es sich auch mal sich mit dem Index von Dataframes zu beschäftigen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Saar-Pfalz666
User
Beiträge: 16
Registriert: Freitag 7. September 2018, 14:00

Sehr gut danke.
Ich hab jetzt was ich nicht brauche gelöscht und dann neu sortiert.

Mit meiner simplen Test-Datei funktioniert alles reibungslos. Nur mit meinem Orginal hapert es noch.
Ich glaub es gibt Probleme bei den Nachkommastellen. Gibt es hier eine Anweisung die Global wirkt ?
Oder muss ich alle df‘s einzeln parametrieren?
Saar-Pfalz666
User
Beiträge: 16
Registriert: Freitag 7. September 2018, 14:00

Saar-Pfalz666 hat geschrieben: Mittwoch 12. September 2018, 17:45 Gibt es hier eine Anweisung die Global wirkt ?
Oder muss ich alle df‘s einzeln parametrieren?
Da hat mir Google mittlerweile schon gute Dienste geleistet.

Hier nun mein fertiger Code. Er ist wohl nicht der schönste, aber er tut das was er soll.
Wie hätte man das mit dem "data.drop" schöner lösen können?
Jetzt wäre es noch was wenn ich die ungleichen nochmal als Tabelle raus bekommen würde. Das ist aber nur der Feinschliff.

Code: Alles auswählen

import pandas as pd
import numpy as np

data = pd.read_excel('data.xls', 'Sheet1', na_values=['NA'])
hcc = pd.read_excel('hcc.xls', 'Sheet1', na_values=['NA'])
hck = pd.read_excel('hck.xls', 'Sheet1', na_values=['NA'])

#Rundet alle Zahlen aus dem Sheet data.xls auf 2 Nachkommestellen
data = data.round(decimals=2)
    
#Filtert die Spalte "Bezeichung" und "Endprodukt" heraus, da diese in den Tabellen hcc & hck nicht vorhanden sind
data = data.drop('Bezeichnung', 1)
data = data.drop('Endprodukt', 1)
    
#Filtert irrelevante Zeilen heraus
data = data.drop('Start', 1)
data = data.drop('Ende', 1)
data = data.drop('Tage', 1)
data = data.drop('Zeitraum', 1)
    
#Sortiert den Dataframe neu
data = data.reindex(['TTNR', 'Startbestand', 'Zugänge', 'Abgänge', 'Endbestand', 'DLZ', 'Durchschnittsbestand', 'SummeBestand', 'SummeAbgang', 'Stufendurchschnitt', 'Disponent', *range(0)], axis=1)

#Legt die Tabellen hcc.xls und hck.xls zusammen in einen Dataframe
hcc_hck = hcc.append(hck, ignore_index=True)

#Rundet alle Zahlen aus der kombinierten Tabelle hcc.xls und hck.xls auf 2 Nachkommestellen
hcc_hck = hcc_hck.round(decimals=2)

#Filtert irrelevante Zeilen heraus
hcc_hck = hcc_hck.drop('Start', 1)
hcc_hck = hcc_hck.drop('Ende', 1)
hcc_hck = hcc_hck.drop('Tage', 1)
hcc_hck = hcc_hck.drop('Zeitraum', 1)

#Bildet aus data ein array
data_array = data.values

#Bildet aus hcc_hck ein array
hcc_hck_array = hcc_hck.values

#Mapping von data_array
data_check = set(map(tuple, data_array))

#Mapping von hcc_hck_array
hcc_hck_check = set(map(tuple, hcc_hck_array))

#Bildet die symetrische Differenz von data_check und hcc_hck_check
#Das bedeutet das nur Datensätze ausgegeben werden, bei denen nicht in beiden Dateien gleiche Werte gefunden werden
diff = data_check.symmetric_difference(hcc_hck_check)

#Gibt die Anzahl der Unterschiedlichen Datensätze an 
len(diff)

Saar-Pfalz666
User
Beiträge: 16
Registriert: Freitag 7. September 2018, 14:00

Jetzt habe ich die Datei wie ich sie gerne hätte.
Wie kann ich jetzt wieder aus einem "set" ein "DataFrame" machen, um eine "xlsx" auszugeben.
vijayhackr
User
Beiträge: 1
Registriert: Montag 22. Oktober 2018, 10:38

You can write the following code to do the same.
import pandas as pd

df1 = pd.read_excel('excel1.xlsx')
df2 = pd.read_excel('excel2.xlsx')

difference = df1[df1!=df2]
print difference
Antworten