import pandas as pd

Einführung in Datenstrukturen#

In diesem Notebook beschäftigen wir uns mit der sinnvollen Strukturierung von DataFrames sowie dem zeilenweisen Zusammenfügen mehrerer DataFrames.

Bisher hatten wir sehr abstrakte Daten betrachtet: Einkommen als Ausgangspunkt und davon abgeleitete Steuern und Abgaben. Nie hatten wir Referenzen auf bestimmte Personen, oder hatten Zeilen in unseren Datensätzen eine Verbindung miteinander.

Dies ändert sich nun, wenn wir uns Familien anschauen. Kinder betrachten wir erst später, daher besteht in dieser Woche ein Haushalt entweder aus einer oder aus zwei Personen; jeder Haushalt hat in einem DataFrame mit individuellen Daten also eine oder zwei Zeilen.

Zunächst fangen wir aber mit zwei DataFrames an, die nur Haushalte betrachten, einen mit den monatlichen Haushaltseinkommen und einen mit der Zahl der Haushaltsmitglieder.

haushaltseinkommen = pd.DataFrame(
    [
        {"hh_id": 0, "einkommen_m_hh": 3000},
        {"hh_id": 1, "einkommen_m_hh": 3000},
        {"hh_id": 2, "einkommen_m_hh": 3000},
        {"hh_id": 3, "einkommen_m_hh": 1500},
        {"hh_id": 4, "einkommen_m_hh": 1500},
    ],
)
haushaltseinkommen

Bitte beachten Sie, dass wir das Einkommen der Haushalte in der Tabelle haushaltseinkommen mit einem _hh am Ende versehen. Dies tun wir, um später Verwirrungen zu vermeiden, wenn nicht klar ist, ob es um die individuelle oder die Haushaltsebene geht.

haushaltsmitglieder = pd.DataFrame(
    [
        {"hh_id": 0, "n_personen": 2},
        {"hh_id": 1, "n_personen": 2},
        {"hh_id": 2, "n_personen": 2},
        {"hh_id": 3, "n_personen": 1},
        {"hh_id": 4, "n_personen": 1},
    ],
)
haushaltsmitglieder

Index vernünftig setzen ist sinnvoll#

hh_id ist nur relevant zur Identifikation von Zeilen, die Werte selber haben keinerlei Interpretation. Da es sich um eine einzelne Spalte handelt, wird sie zum Typ Index. Es ist hilfreich, damit anstelle des automatisch von Pandas erstellten durchnummerierten Index zu arbeiten.

Achtung: Die folgenden Zellen lassen sich nur einmal ausführen, da sie die ursrprünglichen DataFrames überschreiben und hh_id im Anschluss an die Ausführung nicht mehr als Spalte existiert. Im Fall der Fälle lassen Sie es einfach das ganze Notebook noch einmal von vorne laufen.

Zusammenfügen der beiden DataFrames#

Beide DataFrames haben denselben Index. Dies führt zu einem sogenannten 1:1 merge, eine Zeile aus einem DataFrame entspricht konzeptionell einer Zeile des anderen. (hier stimmt das sogar genau; häufig gibt es jedoch fehlende Werte in einem der DataFrames, weil z.B. Personen ihr Einkommen in einer Umfrage nicht angeben).

Weiterer DataFrame mit dem Geschlecht#

Nun erstellen wir einen DataFrame mit einem personenbezogenen Merkmal, dem Geschlecht. Ein weiteres Merkmal ist die Haushaltsidentifikationsnummer; diese nimmt genau die Werte an, die auch im DataFrame haushalte vorkommen.

geschlecht = pd.DataFrame(
    [
        {"p_id": 0, "hh_id": 0, "geschlecht": "w"},
        {"p_id": 1, "hh_id": 0, "geschlecht": "m"},
        {"p_id": 2, "hh_id": 1, "geschlecht": "w"},
        {"p_id": 3, "hh_id": 1, "geschlecht": "m"},
        {"p_id": 4, "hh_id": 2, "geschlecht": "w"},
        {"p_id": 5, "hh_id": 2, "geschlecht": "m"},
        {"p_id": 6, "hh_id": 3, "geschlecht": "m"},
        {"p_id": 7, "hh_id": 4, "geschlecht": "w"},
    ],
)
geschlecht

Index setzen ist wieder sinnvoll.#

Sowohl p_id als auch hh_id sind nur relevant zur Identifikation von Zeilen, beides sind keine relevanten Daten. Wiederum ist es sinnvoll, diese als Index zu verwenden. Da es sich um mehr als eine Spalte handelt, wird der Index zu einem Objekt vom Typ MultiIndex.

Bei einem hierarchischen MultiIndex (z.B. Haushalt/Person; Gegenbeispiel Person/Zeitpunkt) empfiehlt es sich, die gröbere Ebene zuerst zu setzen.

Zusammenfügen von haushalte und geschlecht#

Die DataFrames haushalte und geschlecht haben zwar nicht denselben Index, teilen sich jedoch die gemeinsame Indexspalte hh_id. Da ein Wert von hh_id potentiell mehr als eine Zeile in geschlecht indiziert, führt dies zu einem sogenannten 1:many merge.