Zum Inhalt
wannacode

Breit und lang: pivot_table und melt

Kurz gesagt: pivot_table macht eine breite Tabelle mit einer Spalte für jede Kategorie, und melt bringt die lange mit einer Zeile für jeden Fakt zurück; die Form wählst du nach der Frage.

Problem

„Gib es mir nach Monat und Kategorie“

Der Chef will den Umsatz des Jahres in einer Tabelle: die Monate nach unten, die Kategorien nach rechts, wie in Excel. Du weißt, wie: die Zeilen mit den Bestellungen, den Produkten und den Kategorien verbinden (merge) und nach zwei Schlüsseln gruppieren. Stornierte Bestellungen sind kein Umsatz, also entfernst du sie. Die Geschenkkarte hat keine Kategorie und bekommt einen eigenen Namen, sonst würde sie aus den Gruppen fallen:

PythonDaten: die Tabellen des Shops

Die Zahlen stimmen, aber es sind 84 Zeilen: 12 Monate mal 7 Kategorien, untereinander. Um den Januar mit dem Juli zu vergleichen, durchsuchst du die Liste mit den Augen. Die Tabelle, die der Chef will, hat 12 Zeilen und 7 Spalten mit denselben 84 Zahlen.

Der Monat ist hier seine Nummer: 1 ist der Januar 2026, und 11 und 12 sind November und Dezember 2025.

Die Idee

Lang und breit

Dieselben Zahlen können in zwei Formen stehen:

  • Lang: eine Zeile für jeden Fakt. Die Spalten sind month, category und revenue, und jedes Paar aus Monat und Kategorie ist eine eigene Zeile.
  • Breit: eine Zeile für jeden Monat und eine Spalte für jede Kategorie. Die Kategorie ist keine Spalte mehr: Ihre Werte sind zu Spaltennamen geworden.

Von lang zu breit geht es mit dem Ergebnis von groupby in einer Zeile: unstack() nimmt die letzte Ebene des Index (die Kategorie) und macht daraus Spalten:

PythonDaten: die Tabellen des Shops

Die Form ist (12, 7): 12 Monate und 7 Kategorien. Januar: 593 € Küche, 2.038 € Milchprodukte, 1.225 € Getränke.

Die Idee

Direkt breit: pivot_table

pivot_table gruppiert und ordnet in einem Schritt an. Du sagst ihm vier Dinge:

  • index: was in die Zeilen kommt (der Monat);
  • columns: was zu Spalten wird (die Kategorie);
  • values: mit welcher Spalte es arbeitet (der Umsatz);
  • aggfunc: wie es rechnet ('sum').
PythonDaten: die Tabellen des Shops

Jetzt kannst du es auf einen Blick lesen. Der Dezember ist der Gipfel: Die Küche macht 3.241 €, über das Vierfache eines gewöhnlichen Monats, und die Geschenkkarte 2.160 €. Der Sommer bringt Getränke und Obst: Die Getränke sind im Juli 1.756 € gegen 1.225 € im Januar. Der September ist fast überall schwach. Warum, finden wir im Projekt heraus.

Genauer, für Neugierige

Es gibt auch pivot ohne „table“: Es ordnet nur an und addiert nicht. Wenn ein Paar aus Monat und Kategorie in mehr als einer Zeile vorkommt, stoppt pivot mit einem Fehler, während pivot_table sie mit aggfunc zusammenfasst. Für rohe Zeilen brauchst du pivot_table.

Probier es aus

Stück nach Kategorie

Wie viele Stück hat jede Kategorie in jedem Monat verkauft? Leg in units eine Tabelle mit den Kategorien in den Zeilen und den Monaten in den Spalten ab.

PythonDaten: die Tabellen des Shops

Die Idee

Leere Zellen: fill_value

In der breiten Tabelle hat jedes Paar eine Zelle, auch wenn es das Paar in den Daten nicht gibt. Hier steht, wie viel jeder Kunde in den 60 Bestellungen aus jeder Kategorie gekauft hat:

PythonDaten: die Tabellen des Shops

35 Zellen sind NaN. Kunde 3 hat kein Brot, keine Reinigung und keine Getränke gekauft. Hier heißt leer „null Käufe“, nicht „wir wissen es nicht“. Also ist es richtig, durch null zu ersetzen: fill_value=0.

PythonDaten: die Tabellen des Shops

Das ist der Fall aus der Lektion über Zusammenfassungen, in dem 0 der richtige Ersatz ist: Die Null bedeutet wirklich null. Wenn die Zelle leer wäre, weil ein Bericht fehlte, würde die Null lügen.

Die Idee

Die Summen: margins

margins=True fügt eine Zeile und eine Spalte All mit den Summen hinzu. Hier sind zwei der Kategorien und die Summe zu sehen:

PythonDaten: die Tabellen des Shops

Die Spalte All ist der Umsatz des Monats, und die Zeile All ist der Umsatz der Kategorie für das Jahr: 11.304 € Küche, 17.811 € Getränke. In der Ecke steht die Summe: 111.186,20 €. Der September ist 7.129 €, weniger als der August (8.813 €) und der Oktober (9.920 €).

Die Idee

Zurück zu lang: melt

Der Chef schickt den Plan für die nächsten drei Monate. Die Tabelle kommt aus Excel und ist breit: eine Zeile pro Kategorie und eine Spalte pro Monat.

Eine breite Tabelle ist gut zum Lesen, aber nicht zum Arbeiten. Der Monat ist keine Spalte, er steht in den Spaltennamen, und es gibt nichts zum Gruppieren. melt schmilzt sie zurück zu einer langen: id_vars ist die Spalte, die bleibt, var_name benennt die Spalte mit den alten Spaltennamen und value_name die Spalte mit den Zahlen:

PythonDaten: die Tabellen des Shops

Aus 7 Zeilen und 4 Spalten werden 21 Zeilen und 3 Spalten: Jede Zahl des Plans ist eine eigene Zeile. Jetzt ist der Monat eine Spalte, und groupby funktioniert:

PythonDaten: die Tabellen des Shops

Der Plan für den Dezember ist 16.650 €, für den November 9.700 €.

Probier es aus

Welche Form wofür

1. Du hast eine lange Tabelle plan_long mit den Spalten category, month und plan. Wie bekommst du den Plan für jeden Monat?
2. Du willst mit df.plot() eine Linie pro Kategorie über die Monate, und df.plot() zeichnet eine Linie für jede Spalte. Welche Tabelle gibst du ihm?

Übung

Der Bericht für den Chef

Mach den Bericht von der ersten Karte: report mit dem Umsatz nach Monat (Zeilen) und Kategorie (Spalten), mit den Summen All. Lege dann in dec_share ab, welchen Teil des Jahresumsatzes der Dezember ausmacht.

PythonDaten: die Tabellen des Shops

Wie hoch ist der Plan für die drei Monate zusammen für jede Kategorie? Mach plan lang (plan_long mit den Spalten category, month und plan) und lege die Summe für jede Kategorie in per_category ab.

PythonDaten: die Tabellen des Shops

Test

Teste dich

1. Was berechnet pivot_table, wenn du aggfunc nicht angibst?
2. In der Tabelle „Kunde × Kategorie“ hat Kunde 3 keine Getränke gekauft, und die Zelle ist NaN. Wann ist fill_value=0 richtig?
3. Eine Tabelle aus Excel hat die Spalten category, 2026-11, 2026-12 und 2027-01. Was macht sie lang?
4. Was fügt margins=True hinzu?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·