Ich versuche genau hervorzuheben, was sich zwischen zwei Datenrahmen geändert hat.
Angenommen, ich habe zwei Python Pandas-Datenrahmen:
"StudentRoster Jan-1":
id Name score isEnrolled Comment
111 Jack 2.17 True He was late to class
112 Nick 1.11 False Graduated
113 Zoe 4.12 True
"StudentRoster Jan-2":
id Name score isEnrolled Comment
111 Jack 2.17 True He was late to class
112 Nick 1.21 False Graduated
113 Zoe 4.12 False On vacation
Mein Ziel ist es, eine HTML-Tabelle auszugeben, die:
- Identifiziert geänderte Zeilen (int, float, boolean, string)
Gibt Zeilen mit denselben, ALTEN und NEUEN Werten aus (idealerweise in eine HTML-Tabelle), damit der Verbraucher klar erkennen kann, was sich zwischen zwei Datenrahmen geändert hat:
"StudentRoster Difference Jan-1 - Jan-2": id Name score isEnrolled Comment 112 Nick was 1.11| now 1.21 False Graduated 113 Zoe 4.12 was True | now False was "" | now "On vacation"
Ich nehme an, ich könnte einen zeilenweisen und einen spaltenweisen Vergleich durchführen, aber gibt es einen einfacheren Weg?
df.compare
tun - .Antworten:
Der erste Teil ähnelt Constantine. Sie können den Booleschen Wert ermitteln, dessen Zeilen leer sind *:
Dann können wir sehen, welche Einträge sich geändert haben:
Hier ist der erste Eintrag der Index und der zweite die geänderten Spalten.
* Hinweis: Es ist wichtig , dass
df1
unddf2
hier den gleichen Index teilen. Um diese Unklarheit zu überwinden, können Sie sicherstellen, dass Sie nur die freigegebenen Labels mit verwendendf1.index & df2.index
, aber ich denke, ich werde das als Übung belassen.quelle
df1
, was zuerst kommtdf2
, mit dem , was zuerst kommt , unabhängig vom Wert des Index. JFYI für den Fall, dass ich nicht die einzige Person bin, für die dies nicht offensichtlich war. ; D Danke!nan
in beiden DF1 und df1, wird diese Funktion berichten sie , wie aus geändert habennan
zunan
. Dies liegt daran, dassnp.nan != np.nan
zurückgegeben wirdTrue
.Hervorheben des Unterschieds zwischen zwei DataFrames
Mit der DataFrame-Stileigenschaft können Sie die Hintergrundfarbe der Zellen hervorheben, bei denen ein Unterschied besteht.
Verwenden Sie die Beispieldaten aus der ursprünglichen Frage
Der erste Schritt besteht darin, die DataFrames horizontal mit der
concat
Funktion zu verketten und jeden Frame mit demkeys
Parameter zu unterscheiden:Es ist wahrscheinlich einfacher, die Spaltenebenen zu vertauschen und dieselben Spaltennamen nebeneinander zu platzieren:
Jetzt ist es viel einfacher, die Unterschiede in den Frames zu erkennen. Wir können jedoch noch weiter gehen und die
style
Eigenschaft verwenden, um die unterschiedlichen Zellen hervorzuheben. Dazu definieren wir eine benutzerdefinierte Funktion, die Sie in diesem Teil der Dokumentation sehen können .Dadurch werden Zellen hervorgehoben, bei denen beide Werte fehlen. Sie können sie entweder füllen oder zusätzliche Logik bereitstellen, damit sie nicht hervorgehoben werden.
quelle
df_final[(df != df2).any(1)].style.apply(highlight_diff, axis=None)
Diese Antwort erweitert einfach @Andy Haydens, macht es widerstandsfähig gegenüber numerischen Feldern
nan
und verpackt es in eine Funktion.Also mit Ihren Daten (leicht bearbeitet, um eine NaN in der Bewertungsspalte zu haben):
Ausgabe:
quelle
druckt
quelle
id
als Index zu verwenden, wirddf.groupby(level='id')
ein FehlerIch habe mich diesem Problem gestellt, aber eine Antwort gefunden, bevor ich diesen Beitrag gefunden habe:
Laden Sie Ihre Daten basierend auf der Antwort von unutbu ...
... definieren Sie Ihre Diff- Funktion ...
Dann können Sie einfach ein Panel verwenden, um Folgendes zu schließen:
Übrigens, wenn Sie sich in IPython Notebook befinden, können Sie eine farbige Diff- Funktion verwenden, um Farben zu geben, je nachdem, ob die Zellen unterschiedlich, gleich oder links / rechts null sind:
quelle
my_panel = pd.Panel(dict(df1=df1,df2=df2))
die Funktion aufzunehmenreport_diff()
? Ich meine, ist es möglich, dies zu tun:print report_diff(df1,df2)
und die gleiche Ausgabe wie Ihre Druckanweisung zu erhalten?pd.Panel(dict(df1=df1,df2=df2)).apply(report_diff, axis=0)
- das ist fantastisch!!!Wenn Ihre beiden Datenrahmen dieselben IDs enthalten, ist es eigentlich ziemlich einfach herauszufinden, was sich geändert hat.
frame1 != frame2
Wenn Sie dies tun , erhalten Sie einen booleschen DataFrame, in dem sich alleTrue
Daten geändert haben. Daraus können Sie leicht den Index jeder geänderten Zeile abrufen, indem Sie dies tunchangedids = frame1.index[np.any(frame1 != frame2,axis=1)]
.quelle
Ein anderer Ansatz mit concat und drop_duplicates:
Ausgabe:
quelle
Nachdem ich mit der Antwort von @ journois herumgespielt hatte, konnte ich sie aufgrund der Deprivation von Panel mit MultiIndex anstelle von Panel zum Laufen bringen .
Erstellen Sie zunächst einige Dummy-Daten:
Definieren Sie dann Ihre Diff- Funktion. In diesem Fall verwende ich die aus seiner Antwort.
report_diff
Bleibt gleich:Dann werde ich die Daten zu einem MultiIndex-Datenrahmen verketten:
Und zum Schluss werde ich
report_diff
jede Spaltengruppe nach unten anwenden :Dies gibt aus:
Und das ist alles!
quelle
Erweiterte Antwort von @cge, die für eine bessere Lesbarkeit des Ergebnisses ziemlich cool ist:
Vollständiges Demonstrationsbeispiel:
quelle
Hier ist eine andere Möglichkeit, Select und Merge zu verwenden:
Hier ist das gleiche aus einem Jupyter-Screenshot:
quelle
Pandas> = 1,1:
DataFrame.compare
Mit pandas 1.1 können Sie die Ausgabe von Ted Petrou im Wesentlichen mit einem einzigen Funktionsaufruf replizieren. Beispiel aus den Dokumenten:
Hier bezieht sich "self" auf den LHS-Datenrahmen, während "other" auf den RHS-Datenrahmen verweist. Standardmäßig werden gleiche Werte durch NaNs ersetzt, sodass Sie sich nur auf die Unterschiede konzentrieren können. Wenn Sie auch gleiche Werte anzeigen möchten, verwenden Sie
Sie können die Vergleichsachse auch ändern mit
align_axis
:Dies vergleicht die Werte zeilenweise statt spaltenweise.
quelle
Eine Funktion, die einen asymmetrischen Unterschied zwischen zwei Datenrahmen findet, ist unten implementiert: (Basierend auf dem eingestellten Unterschied für Pandas ) GIST: https://gist.github.com/oneryalcin/68cf25f536a25e65f0b3c84f9c118e03
Beispiel:
quelle
Pandas als pd importieren numpy als np importieren
df = pd.read_excel ('D: \ HARISH \ DATA SCIENCE \ 1 MEIN Training \ MUSTERDATEN & projs \ KRICKETDATEN \ IPL-SPIELERLISTE \ IPL-SPIELERLISTE _ harish.xlsx')
df1 = srh = df [df ['TEAM']. str.contains ("SRH")] df2 = csk = df [df ['TEAM']. str.contains ("CSK")]
srh = srh.iloc [:, 0: 2] csk = csk.iloc [:, 0: 2]
csk = csk.reset_index (drop = True) csk
srh = srh.reset_index (drop = True) srh
new = pd.concat ([srh, csk], axis = 1)
new.head ()
** SPIELERTYP SPIELERTYP
0 David Warner Batsman ... MS Dhoni Kapitän
1 Bhuvaneshwar Kumar Bowler ... Ravindra Jadeja Allrounder
2 Manish Pandey Batsman ... Suresh Raina Allrounder
3 Rashid Khan Arman Bowler ... Kedar Jadhav Allrounder
4 Shikhar Dhawan Batsman .... Dwayne Bravo Allrounder
quelle