import numpy as np
import pandas as pd

pd.options.plotting.backend = "plotly"

Präsenzphase: Ehegattensplitting und Lohnsteuerklassen#

In dieser Übung geht es um die unterschiedlichen Möglichkeiten Ehepaare zu besteuern.

  • Die erste Aufgabe beschäftigt sich mit der Einkommensteuer, d.h., der gesamten Steuerlast des Paares am Ende eines Jahres.

  • In der zweiten Aufgabe geht es um die Lohnsteuer und damit um die individuellen Nettolöhne am Ende eines Monats.

Sie finden hier zunächst eine Wiederholung der Funktionen aus den letzten Wochen ergänzt um

a) eine Funktion, die Einkommenssteuer + Soli kombiniert und auf die Monatsebene herunterechnet, sowie

b) eine Funktion, die die gesamten monatlichen Sozialversicherungsbeiträge eines Individuums berechnet.

Im gesamten Notebook bleiben wir auf der monatlichen Ebene. Das heißt, wir teilen auch die jährlich berechnete Einkommensteuer durch 12, bevor sie im Datensatz abgespeichert wird.

def einkommensteuer_2023(zu_versteuerndes_einkommen):
    """Berechne Einkommensteuer 2023.

    Args:
        zu_versteuerndes_einkommen (float): Zu versteuerndes Einkommen

    Output:
        Steuerlast(float): Steuerlast 2023
    """
    x = np.floor(zu_versteuerndes_einkommen)
    y = (x - 10_908) / 10_000
    z = (x - 15_999) / 10_000

    if x <= 10_908:
        e_st = 0
    elif x <= 15_999:
        e_st = np.floor((979.18 * y + 1_400) * y)
    elif x <= 62_809:
        e_st = np.floor((192.59 * z + 2_397) * z + 966.53)
    elif x <= 277_825:
        e_st = np.floor(0.42 * x - 9_972.98)
    else:
        e_st = np.floor(0.45 * x - 18_307.73)
    return e_st


def soli(einkommensteuer, freigrenze, soli_rate_max):
    """Berechne Solidaritätszuschlag.

    Args:
        einkommensteuer (float): Einkommensteuerlast
        freigrenze (float): Solidaritätszuschlagsfreigrenze für die Einkommensteuerlast
        soli_rate_max (float): Maximaler Grenzsteuersatz des Solidaritätszuschlags

    Output:
        soli (float): Steuerlast aus dem Solidaritätszuschlag
    """
    soli = np.minimum(
        0.055 * einkommensteuer,
        np.maximum(soli_rate_max * (einkommensteuer - freigrenze), 0),
    )

    return soli


def soli_einkommensteuer_m(einkommen_m):
    """Berechne Einkommenssteuer + Soli auf den Monat runtergerechnet.

    Annahme: Einkommen bleibt konstant über das Jahr.

    Args:
        einkommen_m (float): monatliches Einkommen

    Return:
        float: Summe der Einkommensteuer und des Solidaritätszuschlag pro Monat

    """
    steuer = einkommensteuer_2023(zu_versteuerndes_einkommen=einkommen_m * 12)
    soli_betrag = soli(einkommensteuer=steuer, freigrenze=16_956, soli_rate_max=0.119)

    return (steuer + soli_betrag) / 12


def soz_vers_beitrag(
    bruttolohn_m,
    arbeitnehmersatz,
    bemessungsgrenze_m,
):
    """Berechne Beitrag zu einer der Sozialversicherungen.

    Inputs:

        bruttolohn_m (float): monatliches Bruttoarbeitsentgelt
        arbeitnehmersatz (float): Beitragssatz, der vom Arbeitnehmer zu zahlen ist
        bemessungsgrenze_m (float): Monatliche Beitragsbemessungsgrenze

    Output:

        arbeitnehmerbeitrag (float): Der Beitrag in Euro zur Sozialversicherung.

    """
    e_bis_bbg = np.minimum(bruttolohn_m, bemessungsgrenze_m)
    arbeitnehmerbeitrag = e_bis_bbg * arbeitnehmersatz

    return np.round(arbeitnehmerbeitrag, 2)


def gesamt_sozialversicherung(bruttolohn_m):
    """Berechne die gesamten Sozialabgaben eines Erwachsenen ohne Kinder.

    Args:
        bruttolohn_m (float): monatliches Bruttoarbeitsentgelt

    Return:
        float: monatliche Sozialversicherungsbeiträge

    """
    beitrag = (
        soz_vers_beitrag(bruttolohn_m, arbeitnehmersatz=0.093, bemessungsgrenze_m=7_300)
        + soz_vers_beitrag(
            bruttolohn_m,
            arbeitnehmersatz=0.013,
            bemessungsgrenze_m=7_300,
        )
        + soz_vers_beitrag(
            bruttolohn_m,
            arbeitnehmersatz=0.073,
            bemessungsgrenze_m=4_987.50,
        )
        + soz_vers_beitrag(
            bruttolohn_m,
            arbeitnehmersatz=0.01525 + 0.0035,
            bemessungsgrenze_m=4_987.50,
        )
    )

    return beitrag

Aufgabe 1: Einkommenssteuer (105 min)#

In dieser Aufgabe geht es um die Einkommenssteuer und nicht um die Lohnsteuer. Bei dieser Aufgabe sind immer zwei Ebenen zu beachten, das Ehepaar und das Individuum.

Annahmen

  • Pauschalen (Vorsorge-, Werbungskosten-, etc.) und andere Abzüge bleiben unberücksichtigt, so dass das Einkommen identisch zum zu versteuerndem Einkommen ist.

  • Sämtliches Einkommen wird aus abhängiger, sozialversicherungspflichtiger Beschäftigung erzielt.

  • Das monatliche Einkommen ist konstant über das Jahr.

  • Ehepaare haben keine Kinder (nur wichtig für den Pflegeversicherungsbeitrag).

Datenstruktur

Das vorprogrammierte DataFrame hat heute eine etwas andere Struktur als die letzten Wochen. Die Datenstruktur ist ähnlich zu Datenstrukturen, die typischerweise in Umfrage- und Administrativdaten vorkommen. Sie werden solche Datenstrukturen in der Zukunft öfter nutzen.

Das DataFrame beinhaltet Ehepaare.

Es beinhaltet 3 Spalten und 2 Indexspalten, die in einem sogenannten Multiindex kombiniert sind.

Indexe:

  • hh_id: Identifiziert einen Haushalt. Ehepartner haben somit dieselbe hh_id

  • p_id: Identifiziert eine Person. Jedes Individuum im Datensatz hat somit eine eigene p_id.

Spalten

  • partner_typ: Erstverdiener oder Zweitverdiener (gibt an, welche Person in der Partnerschaft mehr verdient)

  • bruttolohn_m: monatlicher Bruttolohn eines Individuums. Größen vermeiden Mini- und Midijobs

  • sozialabgaben_m: monatliche Sozialabgaben eines Individuums

1.1 Verständnis der Datenstruktur (15 min)#

Bitte legen Sie hier den Fokus darauf, die Struktur des resultierenden DataFrames zu verstehen! Der genaue Weg dorthin ist nicht entscheidend.

# Alle Kombinationen der Einkommen als Karthesisches Produkt
bruttolohn_m1 = [3000, 4000, 5000, 10000]
bruttolohn_m2 = list(np.arange(2000, 6500, 500))
ind = pd.MultiIndex.from_product(
    [bruttolohn_m1, bruttolohn_m2],
    names=["bruttolohn_m1", "bruttolohn_m2"],
)
df_exogen = pd.DataFrame(data={"hh_id": np.arange(1, len(ind) + 1)}, index=ind)

# Behalte nur diejenigen Paare, für die bruttolohn_m1 > bruttolohn_m2
df_exogen = df_exogen.query("bruttolohn_m1 >= bruttolohn_m2")

# Stecke Einkommen in Spalten
df_exogen = df_exogen.reset_index()

# Eine Zeile pro Individuum statt pro Haushalt
df_exogen = (
    pd.wide_to_long(df=df_exogen, stubnames="bruttolohn_m", i="hh_id", j="verdienst_nr")
    .sort_index()
    .reset_index()
)
# reset_index() hat einen laufenden Index erstellt, nutze den als Personen-ID
df_exogen.index.name = "p_id"

# Partnertypen
df_exogen["partner_typ"] = df_exogen["verdienst_nr"].map(
    {1: "Erstverdiener", 2: "Zweitverdiener"},
)
# Index vernünftig setzen, nur relevante Spalten behalten
df_exogen = (
    df_exogen.reset_index()
    .set_index(["hh_id", "p_id"])
    .sort_index()[["partner_typ", "bruttolohn_m"]]
)
# Sozialabgaben berechnen
df_exogen["sozialabgaben_m"] = df_exogen["bruttolohn_m"].apply(
    gesamt_sozialversicherung,
)
df_exogen.head(12)
df_exogen.tail(6)

Hinzufügen des Bruttolohns auf Haushaltsebene#

Nun nutzen wir die groupby-Methode sowie die Summenaggregation (Reduktion), um den monatlichen Bruttolohn des Haushalts hinzuzufügen.

Da wir die separate Variable nur temporär benötigen, lassen wir sie gemäß der Python-Konvention mit einem Unterstrich beginnen.

_bruttolohn_m_hh = df_exogen["bruttolohn_m"].groupby("hh_id").sum()
_bruttolohn_m_hh.name = "bruttolohn_m_hh"
_bruttolohn_m_hh
# Achtung: Der join-Befehl lässt sich nur einmal ausführen, weil die Spalte
# "bruttolohn_m_hh" sonst schon vorhanden ist.
#
# Ansonsten nochmal ausführen ab der Zelle, in der *df_exogen* erstellt wird!

df_exogen = df_exogen.join(_bruttolohn_m_hh)
df_exogen

Erstellen des Partnereinkommens und Umsortieren der Spalten#

Später wird es hilfreich sein, auch das Partnereinkommen zu kennen.

Wir berechnen es einfach als Differenz des Haushalts- und eigenen Einkommens.

Anschließend sortieren wir die Spalten sinnvoll um.

df_exogen["bruttolohn_m_partner"] = (
    df_exogen["bruttolohn_m_hh"] - df_exogen["bruttolohn_m"]
)
df_exogen = df_exogen[
    [
        "partner_typ",
        "bruttolohn_m",
        "bruttolohn_m_partner",
        "bruttolohn_m_hh",
        "sozialabgaben_m",
    ]
]
df_exogen.head()

1.2 Berechnung der Gesamtabgaben und das Nettogesamteinkommen der Ehepaare unter Individualbesteuerung (20 min)#

Bitte versuchen Sie hier en detail nachzuvollziehen, was passiert!

def ind_gesamtbelastung_m(bruttolohn_m):
    """Berechne die individuelle Gesamtbelastung mit Steuern und Sozialabgagen.

    Args:
        bruttolohn_m (pd.Series): Monatliches Lohneinkommen.

    Return:
        float: Monatliche Gesamtbelastung mit Steuern und Sozialabgaben.

    """
    sozialabgaben_m = gesamt_sozialversicherung(bruttolohn_m)
    steuer_soli_m = soli_einkommensteuer_m(bruttolohn_m)

    return (sozialabgaben_m + steuer_soli_m).round(2)
# Individuelle Steuer- und Sozialabgabenlast
df_ind_besteuerung = df_exogen.copy()
df_ind_besteuerung["gesamtbelastung_m"] = df_exogen["bruttolohn_m"].apply(
    ind_gesamtbelastung_m,
)
df_ind_besteuerung.head(10)
# Achtung: Der join-Befehl lässt sich nur einmal ausführen, weil die Spalte
# "gesamtbelastung_m_hh" sonst schon vorhanden ist.
#
# Ansonsten nochmal ausführen ab der Zelle, in der *df_ind_besteuerung* erstellt wird!

_gesamtbelastung_m_hh = df_ind_besteuerung["gesamtbelastung_m"].groupby("hh_id").sum()
_gesamtbelastung_m_hh.name = "gesamtbelastung_m_hh"
df_ind_besteuerung = df_ind_besteuerung.join(_gesamtbelastung_m_hh)
df_ind_besteuerung.head(5)
# Nettolohn

df_ind_besteuerung["nettolohn_m"] = (
    df_ind_besteuerung["bruttolohn_m"] - df_ind_besteuerung["gesamtbelastung_m"]
)
df_ind_besteuerung.head(10)

1.3 Berechnung der Gesamtabgaben und des Nettogesamteinkommens der Haushalte unter Ehegattensplitting (25 min)#

Berechnen Sie die Gesamtbelastung und das Nettogesamteinkommen für einen Haushalt mit Ehegattensplitting.

Wir beginnen wieder mit einer Kopie von df_exogen.

df_ehegattensplitting = df_exogen.copy()
df_ehegattensplitting.head()

Um die Berechnung des Haushaltseinkommens mit Ehegattensplitting zu erleichtern, schauen wir uns zunächst die Berechnung für einen einzigen Haushalt, bestehend aus zwei Personen, an.

minimalbeispiel = df_ehegattensplitting.query("hh_id == 1").copy()
minimalbeispiel

Berechnen Sie die Gesamtbelastung dieses Haushalts indem Sie die Sozialversicherungsabgaben und Einkommensteuerzahlungen auf Haushaltsebene berechnen und summieren. Nutzen Sie dafür ausschließlich den minimalbeispiel DataFrame.

Dafür starten Sie bitte mit den folgenden vier Zellen und ersetzen die Nullen durch passende Ausdrücke.

Hinweis: In den ersten beiden Ausdrücken benötigen Sie Reduktionsoperationen, d.h., aus zwei Zeilen einer Spalte des Dataframes minimalbeispiel wird jeweils eine Zahl

durchschnitt_bruttolohn_m = 0
durchschnitt_bruttolohn_m
sozialabgaben_m_hh = 0
sozialabgaben_m_hh
steuer_soli_m_hh = 0
steuer_soli_m_hh
gesamtbelastung_m_hh = sozialabgaben_m_hh + steuer_soli_m_hh
gesamtbelastung_m_hh

Nun können wir die Gesamtbelastung des Haushalts wieder zurück in den DataFrame stecken.

minimalbeispiel["gesamtbelastung_m_hh"] = gesamtbelastung_m_hh
minimalbeispiel

Nun können wir diese Berechnung für alle Haushalte durchführen. Dies tun wir, indem wir den eben erstellten code in eine Funktion stecken und mittels der .apply()-Methode auf Haushaltsgruppen des DataFrames df_ehegattensplitting anwenden.

Passen Sie zunächst die Funktion ehegattensplitting an, in dem Sie die Nullen wie eben ersetzen. Bitte beachten Sie, das hh_data immer zwei Zeilen des DataFrames enthalten wird. Die Struktur ist also identisch zum Minimalbeispiel. an.

def ehegattensplitting(hh_data):
    """Berechne die Gesamtabgaben unter Ehegattensplitting.

    Args:
        hh_data (pd.DataFrame): DataFrame mit nur einem Ehepaar (also zwei Zeilen)

    Return:
        float: Gesamtbelastung.

    """
    sozialabgaben_m_hh = 0

    steuer_soli_m_hh = 0

    gesamtbelastung_m_hh = sozialabgaben_m_hh + steuer_soli_m_hh

    return np.round(gesamtbelastung_m_hh, 2)

Nutzen Sie jetzt die ehegattensplitting Funktion um df_ehegattensplitting eine weitere Spalte mit der Gesamtbelastung unter Ehegattensplittung hinzuzufügen. Bevor Sie die Spalte hinzufügen, nennen Sie sie gesamtbelastung_m_hh.

Tipp:

  • Nutzen Sie .groupby("hh_id").apply() um Funktionen auf Haushaltsebene anzuwenden. Dokumentation der Methode

  • Nutzen sie data.join() um die Datensätze auf Haushalts- und individueller Ebene zusammenzufügen. https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.join.html

  • Am Ende sehen die Berechnungen sehr ähnlich aus wie zuvor für das Gesamteinkommen und die Gesamtbelastung unter individueller Besteuerung. Lediglich die Aggregationsfunktion ist nun komplizierter als eine Summe.

Berechnen Sie abschließend Gesamtbelastung und Nettoeinkommen auf individueller (!) Ebene unter Ehegattensplitting.

Zusammenfügen der beiden DataFrames#

Wir nutzen die concat-Funktion aus pandas und setzen einen Index, um die beiden DataFrames für die unterschiedlichen Besteuerungsarten zu stapeln.

df = pd.concat(
    [df_ind_besteuerung, df_ehegattensplitting],
    keys=["Individuelle Besteuerung", "Ehegattensplitting"],
    names=["besteuerungsart", "hh_id", "p_id"],
)
df

1.4 Grenzbelastung (25 min)#

Das Ehegattensplitting wird häufig kritisiert, weil der Ehepartner mit geringerem Einkommen mit einer höheren Grenzbelastung konfrontiert ist, als wenn er unverheiratet wäre. Dieses Argument wollen wir in diesem Aufgabenteil besser verstehen. Versuchen Sie bitte den Code im Detail nachzuvollziehen.

Wir ziehen zunächst nur die Zweitverdiener heraus und behalten die relevanten Spalten.

# Umformatierte Daten.
df_zweitverdiener = df.query("partner_typ == 'Zweitverdiener'").copy()[
    ["bruttolohn_m_partner", "bruttolohn_m", "gesamtbelastung_m_hh", "nettolohn_m"]
]
# Anschauliche Darstellung mit relevantem Index.
df_zweitverdiener.reset_index().set_index(
    ["besteuerungsart", "bruttolohn_m_partner", "bruttolohn_m"],
)[["nettolohn_m"]]

Nun wollen wir schauen, wie sich die Grenzbelastung (pro 500 Euro) des Zweitverdieners mit dessen Einkommen verändert. Dazu verschieben wir zunächst das Einkommen und die Gesamtbelastung um eine Zeile. Um nur innerhalb eines Partnereinkommens zu verschieben, nutzen wir groupby(). Vollziehen Sie nach, weshalb manche Werte als “fehlend” (NaN) im DataFrame zweitverdiener eingetragen sind.

shifted = df_zweitverdiener.groupby(["besteuerungsart", "bruttolohn_m_partner"])[
    [
        "bruttolohn_m",
        "gesamtbelastung_m_hh",
    ]
].shift(-1)
shifted.head()
# Ausrechnnen Grenzbelastung
nenner = shifted["bruttolohn_m"] - df_zweitverdiener["bruttolohn_m"]
zähler = shifted["gesamtbelastung_m_hh"] - df_zweitverdiener["gesamtbelastung_m_hh"]
df_zweitverdiener["grenzbelastung"] = (zähler / nenner).round(3)

# Ordentliches Sortieren und Anschauen
df_zweitverdiener.reset_index().set_index(
    ["besteuerungsart", "bruttolohn_m_partner", "bruttolohn_m"],
)[
    [
        "gesamtbelastung_m_hh",
        "grenzbelastung",
    ]
].head(
    10,
)
df_zweitverdiener.tail()

Plotten Sie nun jeweils für die verschiedenen Einkommen des Partners die Grenzbelastung des Zweitverdieners unter Ehegattensplitting und unter Individualbesteuerung in Abhängigkeit des Einkommens des Zweitverdieners.

Sie sollten also vier Graphen erhalten, jeweils eine für das Einkommen des Partners. Auf der x-Achse ist jeweils das Einkommen des Zweitverdieners geplottet, auf der y-Achse die Grenzbelastung des Haushaltseinkommens bei Mehrarbeit des Zweitverdieners. Jede der Grafiken sollte zwei Linien enthalten, eine für die Individualbesteuerung, eine für Ehegattenplitting.

Nutzen Sie dafür folgende Grundstruktur und ersetzen sie die mit XXX markierten fehlenden Einträge:

df_zweitverdiener.reset_index().plot.line(
    x=XXX,
    y=XXX,
    color=XXX,
    facet_col=XXX,
    title="Grenzbelastung des Zweitverdieners nach Bruttoeinkommen des Erstverdieners",
).for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1] + "€"))

Tipp:

  • Eine unter color abgelegte Variable bestimmt welche Gruppen innerhalb eines Plots dargestellt werden. Wenn ein Plot also aus mehreren “Linien” bestehen soll, legen Sie hier die zugrundeliegende Unterscheidungsvariable ab.

  • Wenn unter facet_col eine Variable abgelegt wurde, wird für jede Ausprägung dieser Variable ein neuer (Sub-)Plot erstellt.

1.5 Interpretation / Anreize (20 min)#

Was sind die Hauptunterschiede zwischen den Besteuerungsarten? Glauben Sie, dass diese unterschiedliche Anreizwirkungen haben (z.B. auf das Arbeitsangebot, heiraten)? Warum, warum nicht?

Aufgabe 2: Steuerklassen (50 min)#

In dieser Aufgabe geht es um die unterschiedlichen Belastungen je nach der Steuerklassenwahl von Ehepartnern in Deutschland (Lohnsteuer, nicht Einkommensteuer). Wie Sie in der Selbstlernphase gelernt haben, können sich Ehepartner zwischen unterschiedlichen Steuerklassen entscheiden.

Benutzen Sie in dieser Aufgabe das erste DataFrame df_exogen aus Aufgabe 1 weiter.

2.1 Lohnsteuer Steuerklassen 3 und 5 (20 min)#

Berechnen Sie den monatlichen Nettolohn (Lohn nach Lohnsteuerabzug und Sozialabgaben) für die Steuerklassen 3 (Erstverdienender) und 5 (Zweitverdienender)

Tipp: Die Lohnsteuer lässt sich recht gut approximieren indem man

  1. den normalen Grundfreibetrag von 9408 Euro / 12 = 784 Euro vom zu versteuernden Einkommen des Erstverdieners abzieht und ihn dem Zweitverdiener hinzurechnet

  2. auf den Resultaten ganz normal Soli und Einkommensteuer berechnet.

Hintergrund, für Aufgabe ignorieren: Die tatsächliche Berechnung der Lohnsteuer in der Steuerklasse 5 is komplizierter (siehe https://www.gesetze-im-internet.de/estg/__39b.html): In den Steuerklassen V und VI ist die Jahreslohnsteuer zu berechnen, die sich aus dem Zweifachen des Unterschiedsbetrags zwischen dem Steuerbetrag für das Eineinviertelfache und dem Steuerbetrag für das Dreiviertelfache des zu versteuernden Jahresbetrags nach § 32a Absatz 1 ergibt; die Jahreslohnsteuer beträgt jedoch mindestens 14 Prozent des zu versteuernden Jahresbetrags, für den 10 898 Euro übersteigenden Teil des zu versteuernden Jahresbetrags höchstens 42 Prozent, für den 28 526 Euro übersteigenden Teil des zu versteuernden Jahresbetrags 42 Prozent und für den 216 400 Euro übersteigenden Teil des zu versteuernden Jahresbetrags 45 Prozent.

Die Gesamtbelastung des Erstverdieners haben wir für Sie berechnet. Die des Zweitverdieners berechnen Sie.

df_exogen.head()
df_steuerklassen_3_5_erstverdiener = df_exogen.query(
    "partner_typ=='Erstverdiener'",
).copy()
df_steuerklassen_3_5_erstverdiener["gesamtbelastung_m"] = df_exogen[
    "bruttolohn_m"
].apply(
    lambda x: soli_einkommensteuer_m(x - 784) + gesamt_sozialversicherung(x),
)

Nun fügen wir die beiden DataFrames für Erst- und Zweitverdiener erneut zusammen:

df_steuerklassen_3_5 = pd.concat(
    [df_steuerklassen_3_5_erstverdiener, df_steuerklassen_3_5_zweitverdiener],
).sort_values(["hh_id", "p_id", "partner_typ"])
df_steuerklassen_3_5.head()

Zuletzt berechnen wir den Nettolohn nettolohn_m:

2.2 Abschaffen der Steuerklassen (30 min)#

Wie würde sich das Abschaffen der Steuerklassen (d.h. sowohl Erst- als auch Zweitverdiener sind in Steuerklasse 4) auf das Arbeitsangebot der Ehepartner auswirken?

Vergleichen Sie hierzu den eben berechneten 3/5 Nettolohn des Zweitverdieners mit dem für Steuerklassen 4/4. Gerne erneut mit einer Grafik.

Da Sie insbesondere die Vorsorgepauschale in der Berechnung ignorieren, überschätzen Sie für mittlere und höhere Einkommen den Lohnsteuerabzug teilweise recht stark und unterschätzen das Nettoeinkommen des Besserverdienenden mehr als das des Geringerverdienenden. Beachten Sie das bitte in der Interpretation der Resultate.

Tipp: Die Lohnsteuerzahlung in Steuerklasse 4/4 ohne Faktorgewichtung ist äquivalent zu der Steuerlast der Individualbesteuerung aus Aufgabe 1.

df_steuerklassen = pd.concat(
    [df_ind_besteuerung, df_steuerklassen_3_5],
    keys=["Steuerklasse 4/4", "Steuerklassen 3/5"],
    names=["besteuerungsart", "hh_id", "p_id"],
)
df_steuerklassen.head()
df_steuerklassen.tail()

Aufgabe 3: Pentabilities (10min)#

Bitte bewerten Sie die Beiträge zur Gruppenarbeit in der Pentabilities-App. Bitte vergeben Sie über alle 5 Dimensionen hinweg Punkte für die Verhaltensweisen, welche Sie heute beobachten konnten. Denken Sie bitte daran, sowohl die Beiträge der Kommiliton:innen Ihrer Gruppe als auch Ihre eigenen zu bewerten.