Seite 1 von 1
DataFrame verdichten
Verfasst: Mittwoch 22. Mai 2024, 14:24
von guhamail
Hallo,
ich suche eine Lösung für folgendes Problem:
Ich möchte Werte aus einem DataFrame zusammenschichten.
Aus der Vorgabe soll errechnet werden, wie viel Umsatz jeder Kunde pro Jahr generiert hat.
Code: Alles auswählen
# Vorgabe
df = pd.DataFrame(
{'Jahr': [2020, 2020, 2020, 2021, 2021, 2022, 2022, 2022, 2022'],
'Kunde`': [100, 200, 400, 100, 100, 200, 400, 400, 400],
'Umsatz': [150, 50, 200, 300, 100, 500, 800, 100, 100})
#Code....
#Ergebnis
print(df2)
Jahr Kunde Umsatz
0 2020 100 150
1 2021 100 400
2 2022 100 0
3 2020 200 50
4 2021 200 0
5 2022 200 500
6 2020 400 200
7 2021 400 0
8 2022 400 1000
Wie stelle ich das am besten an?
Vielen Dank für eure Unterstützung.
Re: DataFrame verdichten
Verfasst: Mittwoch 22. Mai 2024, 16:21
von karolus
Hallo
pandas hat eine gute Dokumentation!!
Re: DataFrame verdichten
Verfasst: Mittwoch 22. Mai 2024, 16:57
von __blackjack__
@guhamail: Die ``# Vorgabe`` ist syntaktisch nicht ganz korrekt. Die Fehler sehen so ein bisschen nach OCR aus. Lehrbuchaufgabe‽
Was hast Du denn schon versucht? Wie viel Umsatz jeder Kunde in den Jahren die jeweils in den Daten angegeben sind, generiert hat, lässt sich sehr einfach ermitteln. Man muss ja nur nach Jahr & Kunde gruppieren und dann aufsummieren. karolus hat's ja schon verraten. Dann vielleicht noch den (Multi)Index wieder zu normalen Spalten machen und die Zeilen nach Kunde sortieren, dann hat man das hier:
Code: Alles auswählen
Jahr Kunde Umsatz
0 2020 100 150
3 2021 100 400
1 2020 200 50
4 2022 200 500
2 2020 400 200
5 2022 400 1000
Die fehlenden Zeilen für die Jahre ohne Angaben sind ein bisschen spannender. Da würde ich solange der Multi-Index noch da ist einen neuen, ”vollständigen” erzeugen. `Multindex.from_product()` ist da hilfreich. Und damit dann Re-Indexieren mit einem Füllwert von 0. (Default wäre NaN.)
Re: DataFrame verdichten
Verfasst: Mittwoch 22. Mai 2024, 19:36
von guhamail
karolus hat geschrieben: Mittwoch 22. Mai 2024, 16:21
Hallo
pandas hat eine gute Dokumentation!!
Vielen lieben Dank für den Hinweis. Ich gebe zu, dass ich das aus der Doku hätte raus lesen müssen. Ich tue mir leider immer schwer damit, wenn ich nicht weiß, wonach ich suchen muss.
__blackjack__ hat geschrieben: Mittwoch 22. Mai 2024, 16:57
@guhamail: Die ``# Vorgabe`` ist syntaktisch nicht ganz korrekt. Die Fehler sehen so ein bisschen nach OCR aus. Lehrbuchaufgabe‽
Nein, die Aufgabe entspricht tatsächlich dem wirklichen Leben. Ist auf meiem "Mist" gewachsen.
Da mich die Jahre ohne Umsatz natürlich besonders interessieren, werde ich mich mal mit Multiindex auseinander setzen.
Vielen Dank
Re: DataFrame verdichten
Verfasst: Mittwoch 22. Mai 2024, 19:58
von __blackjack__
Kurz nachdem ich den letzten Beitrag abgeschickt hatte fiel mir noch eine einfachere Lösung ein. Die Zwischenergebnisse sehen so aus:
Code: Alles auswählen
Schritt 1 kennen wir schon:
Umsatz
Kunde Jahr
100 2020 150
2021 400
200 2020 50
2022 500
400 2020 200
2022 1000
Schritt 2 ist eine Umformung der Tabelle mit Kunden und Jahren als
Zeilen/Spalten-Indizes und leeren Kombinationen mit einer 0 gefüllt:
Umsatz
Jahr 2020 2021 2022
Kunde
100 150 400 0
200 50 0 500
400 200 0 1000
Schritt 3 ist einfach die Umkehrfunktion, aber damit haben wir die 0-Werte in den Daten:
Umsatz
Kunde Jahr
100 2020 150
2021 400
2022 0
200 2020 50
2021 0
2022 500
400 2020 200
2021 0
2022 1000
Schritt 4 ist vielleicht optional, wenn man den Index wieder als Spalten haben möchte:
Kunde Jahr Umsatz
0 100 2020 150
1 100 2021 400
2 100 2022 0
3 200 2020 50
4 200 2021 0
5 200 2022 500
6 400 2020 200
7 400 2021 0
8 400 2022 1000
Wobei ich, wenn es darum geht, dass ein Mensch sich einen Überblick verschaffen möchte, wohl schon nach Schritt zwei aufhören würde, weil diese ”2D”-Tabelle IMHO sowohl kompakt, als auch gut verständlich ist.
Re: DataFrame verdichten
Verfasst: Mittwoch 29. Mai 2024, 10:05
von __blackjack__
Hier der Einzeiler für die vier Schritte im letzten Beitrag:
Code: Alles auswählen
result = df.groupby(["Kunde", "Jahr"]).sum().unstack(fill_value=0).stack().reset_index()
# \_________________________________/\____________________/\______/\____________/
# 1 2 3 4