def kinderzuschlag_eink_spanne( hh_id: IntSeries, arbeitsl_geld_2_brutto_eink_hh: FloatSeries, kinderzuschlag_eink_min: FloatSeries, kinderzuschlag_eink_max: FloatSeries, arbeitsl_geld_2_eink_hh: FloatSeries, ) -> BoolSeries: """Check if household income is in income range for child benefit. Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. arbeitsl_geld_2_brutto_eink_hh See :func:`arbeitsl_geld_2_brutto_eink_hh`. kinderzuschlag_eink_min See :func:`kinderzuschlag_eink_min`. kinderzuschlag_eink_max See :func:`kinderzuschlag_eink_max`. arbeitsl_geld_2_eink_hh See :func:`arbeitsl_geld_2_eink_hh`. Returns ------- """ eink_spanne = (hh_id.replace(arbeitsl_geld_2_brutto_eink_hh) >= kinderzuschlag_eink_min) & (hh_id.replace( arbeitsl_geld_2_eink_hh) <= kinderzuschlag_eink_max) return eink_spanne
def date_of_birth(geburtsjahr: IntSeries, geburtsmonat: IntSeries, geburtstag: IntSeries) -> DateTimeSeries: """Create date of birth datetime variable. Parameters ---------- geburtsjahr See basic input variable :ref:`geburtsjahr <geburtsjahr>`. geburtsmonat See basic input variable :ref:`geburtsmonat <geburtsmonat>`. geburtstag See basic input variable :ref:`geburtstag <geburtstag>`. Returns ------- """ out = pd.to_datetime( pd.concat( [ geburtsjahr.rename("year"), geburtsmonat.rename("month"), geburtstag.rename("day"), ], axis=1, )) return out
def wohngeld_miete_bis_2008( mietstufe: IntSeries, immobilie_baujahr_hh: IntSeries, haushaltsgröße: IntSeries, hh_id: IntSeries, kaltmiete_m_hh: FloatSeries, tax_unit_share: FloatSeries, wohngeld_min_miete: FloatSeries, wohngeld_params: dict, ): """Calculate maximal rent subject housing benefit calculation until 2008. Parameters ---------- mietstufe See basic input variable :ref:`mietstufe <mietstufe>`. immobilie_baujahr_hh See basic input variable :ref:`immobilie_baujahr_hh <immobilie_baujahr_hh>`. haushaltsgröße See :func:`haushaltsgröße`. hh_id See basic input variable :ref:`hh_id <hh_id>`. kaltmiete_m_hh See basic input variable :ref:`kaltmiete_m_hh <kaltmiete_m_hh>`. tax_unit_share See :func:`tax_unit_share`. wohngeld_min_miete See :func:`wohngeld_min_miete`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ immobilie_baujahr = hh_id.replace(immobilie_baujahr_hh) # Get yearly cutoff in params which is closest and above the construction year # of the property. We assume that the same cutoffs exist for each household # size. yearly_cutoffs = sorted(wohngeld_params["max_miete"][1], reverse=True) conditions = [immobilie_baujahr <= cutoff for cutoff in yearly_cutoffs] constr_year_category = np.select(conditions, yearly_cutoffs) data = [ wohngeld_params["max_miete"][hh_größe][constr_year][ms] if hh_größe <= 5 else wohngeld_params["max_miete"][5][constr_year][ms] + wohngeld_params["max_miete"]["5plus"][constr_year][ms] * (hh_größe - 5) for hh_größe, constr_year, ms in zip( haushaltsgröße, constr_year_category, mietstufe ) ] wg_miete = ( np.clip(data, a_min=None, a_max=hh_id.replace(kaltmiete_m_hh)) * tax_unit_share ).clip(lower=wohngeld_min_miete) return wg_miete
def wohnbedarf_eltern_anteil( tu_id: IntSeries, anz_kinder_tu: IntSeries, anz_erwachsene_tu: IntSeries, kinderzuschlag_params: dict, ) -> FloatSeries: """Calculate living needs broken down to the parents. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. anz_kinder_tu See :func:`anz_kinder_tu`. anz_erwachsene_tu See :func:`anz_erwachsene_tu`. kinderzuschlag_params See params documentation :ref:`kinderzuschlag_params <kinderzuschlag_params>`. Returns ------- """ kinder_in_tu = tu_id.replace(anz_kinder_tu) erwachsene_in_tu = tu_id.replace(anz_erwachsene_tu) conditions = [] choices = [] for n_adults in [1, 2]: for n_children in [1, 2, 3, 4]: condition = (kinder_in_tu == n_children) & (erwachsene_in_tu == n_adults) choice = kinderzuschlag_params["wohnbedarf_eltern_anteil"][ n_adults][n_children - 1] conditions.append(condition) choices.append(choice) condition = (kinder_in_tu >= 5) & (erwachsene_in_tu == n_adults) choice = kinderzuschlag_params["wohnbedarf_eltern_anteil"][n_adults][4] conditions.append(condition) choices.append(choice) # Add defaults. Is is really necessary or are the former conditions exhaustive? conditions.append(True) choices.append(1) anteil = pd.Series(index=tu_id.index, data=np.select(conditions, choices)) return anteil
def kinderzuschlag_eink_regel_bis_2010( tu_id: IntSeries, hh_id: IntSeries, alleinerziehenden_mehrbedarf_hh: FloatSeries, anz_erwachsene_tu: IntSeries, arbeitsl_geld_2_params: dict, ) -> FloatSeries: """Calculate income relevant for calculation of child benefit until 2010. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. hh_id See basic input variable :ref:`hh_id <hh_id>`. alleinerziehenden_mehrbedarf_hh See :func:`alleinerziehenden_mehrbedarf_hh`. anz_erwachsene_tu See :func:`anz_erwachsene_tu`. arbeitsl_geld_2_params See params documentation :ref:`arbeitsl_geld_2_params <arbeitsl_geld_2_params>`. Returns ------- """ alleinerziehenden_mehrbedarf = hh_id.replace( alleinerziehenden_mehrbedarf_hh) erwachsene_in_tu = tu_id.replace(anz_erwachsene_tu) choices = [ arbeitsl_geld_2_params["regelsatz"] * (1 + alleinerziehenden_mehrbedarf), arbeitsl_geld_2_params["regelsatz"] * arbeitsl_geld_2_params["anteil_regelsatz"]["zwei_erwachsene"] * (2 + alleinerziehenden_mehrbedarf), arbeitsl_geld_2_params["regelsatz"] * arbeitsl_geld_2_params["anteil_regelsatz"]["weitere_erwachsene"] * erwachsene_in_tu, ] data = np.select( [erwachsene_in_tu == 1, erwachsene_in_tu == 2, erwachsene_in_tu > 2], choices, ) eink_regel = pd.Series(index=alleinerziehenden_mehrbedarf.index, data=data) return eink_regel
def kinderzuschlag_ab_juli_2019( hh_id: IntSeries, arbeitsl_geld_2_brutto_eink_hh: FloatSeries, kinderzuschlag_eink_min: FloatSeries, kinderzuschlag_kindereink_abzug: FloatSeries, kinderzuschlag_eink_anrechn: FloatSeries, ) -> FloatSeries: """Calculate preliminary child benefit since 07/2019. Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. arbeitsl_geld_2_brutto_eink_hh See :func:`arbeitsl_geld_2_brutto_eink_hh`. kinderzuschlag_eink_min See :func:`kinderzuschlag_eink_min`. kinderzuschlag_kindereink_abzug See :func:`kinderzuschlag_kindereink_abzug`. kinderzuschlag_eink_anrechn See :func:`kinderzuschlag_eink_anrechn`. Returns ------- """ out = hh_id * 0 condition = hh_id.replace(arbeitsl_geld_2_brutto_eink_hh) >= kinderzuschlag_eink_min out.loc[condition] = ( kinderzuschlag_kindereink_abzug.groupby(hh_id).transform("sum") - kinderzuschlag_eink_anrechn ).clip(lower=0) return out.groupby(hh_id).transform("max")
def kinderzuschlag_eink_anrechn( hh_id: IntSeries, arbeitsl_geld_2_eink_hh: FloatSeries, kinderzuschlag_eink_relev: FloatSeries, kinderzuschlag_params: dict, ) -> FloatSeries: """Calculate parental income subtracted from child benefit. (§6a (6) S. 3 BKGG) Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. arbeitsl_geld_2_eink_hh See :func:`arbeitsl_geld_2_eink_hh`. kinderzuschlag_eink_relev See :func:`kinderzuschlag_eink_relev`. kinderzuschlag_params See params documentation :ref:`kinderzuschlag_params <kinderzuschlag_params>`. Returns ------- """ return (kinderzuschlag_params["kinderzuschlag_transferentzug_eltern"] * (hh_id.replace(arbeitsl_geld_2_eink_hh) - kinderzuschlag_eink_relev)).clip(lower=0)
def haushaltsgröße_hh(hh_id: IntSeries) -> IntSeries: """Count persons in households. Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. Returns ------- IntSeries with the number of persons in household per household. """ return hh_id.groupby(hh_id).size()
def alter_jüngstes_kind(hh_id: IntSeries, date_of_birth: DateTimeSeries, kind: BoolSeries) -> DateTimeSeries: """Calculate the age of the youngest child. Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. date_of_birth See :func:`geburtstag`. kind See basic input variable :ref:`kind <kind>`. Returns ------- """ alter_jüngstes_kind = date_of_birth.loc[kind].groupby(hh_id).max() # Re-index to get NaT for households without children. alter_jüngstes_kind = alter_jüngstes_kind.reindex(index=hh_id.unique()) # Replace hh_ids with timestamps and re-cast to `datetime64[ns]` if there was no kid # which yields object dtype. return hh_id.replace(alter_jüngstes_kind).astype("datetime64[ns]")
def arbeitsl_geld_2_eink( arbeitsl_geld_2_brutto_eink: FloatSeries, eink_st_tu: FloatSeries, tu_id: IntSeries, soli_st_tu: FloatSeries, anz_erwachsene_tu: IntSeries, sozialv_beitr_m: FloatSeries, eink_anr_frei: FloatSeries, ) -> FloatSeries: """Sum up the income for calculation of basic subsistence. Parameters ---------- arbeitsl_geld_2_brutto_eink See :func:`arbeitsl_geld_2_eink`. sozialv_beitr_m See :func:`sozialv_beitr_m`. eink_st_tu See :func:`eink_st_tu`. tu_id See basic input variable :ref:`tu_id <tu_id>`. soli_st_tu See :func:`soli_st_tu`. anz_erwachsene_tu See :func:`anz_erwachsene_tu`. eink_anr_frei See :func:`eink_anr_frei`. Returns ------- Float Series with the income of a person by unemployment insurance. """ return (arbeitsl_geld_2_brutto_eink - tu_id.replace( (eink_st_tu / anz_erwachsene_tu) / 12) - tu_id.replace( (soli_st_tu / anz_erwachsene_tu) / 12) - sozialv_beitr_m - eink_anr_frei).clip(lower=0)
def nettolohn_m( bruttolohn_m: FloatSeries, tu_id: IntSeries, eink_st_tu: FloatSeries, soli_st_tu: FloatSeries, anz_erwachsene_tu: IntSeries, sozialv_beitr_m: FloatSeries, ) -> FloatSeries: """Calculate the net wage. Taxes and social security contributions are needed for the calculation. Parameters ---------- bruttolohn_m See basic input variable :ref:`bruttolohn_m <bruttolohn_m>`. tu_id See basic input variable :ref:`tu_id <tu_id>`. eink_st_tu See :func:`eink_st_tu`. soli_st_tu See :func:`soli_st_tu`. anz_erwachsene_tu See :func:`anz_erwachsene_tu`. sozialv_beitr_m See :func:`sozialv_beitr_m`. Returns ------- """ return (bruttolohn_m - tu_id.replace( (eink_st_tu / anz_erwachsene_tu) / 12) - tu_id.replace( (soli_st_tu / anz_erwachsene_tu) / 12) - sozialv_beitr_m).clip(lower=0)
def tax_unit_share(tu_id: IntSeries, haushaltsgröße: IntSeries) -> FloatSeries: """Calculate the share of tax units in household. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. haushaltsgröße See :func:`haushaltsgröße`. Returns ------- """ return tu_id.groupby(tu_id).transform("count") / haushaltsgröße
def wohngeld_miete_ab_2021( mietstufe: IntSeries, haushaltsgröße: IntSeries, hh_id: IntSeries, kaltmiete_m_hh: FloatSeries, tax_unit_share: FloatSeries, wohngeld_min_miete: FloatSeries, wohngeld_params: dict, ) -> FloatSeries: """Calculate maximal rent subject housing benefit calculation since 2021. Parameters ---------- mietstufe See basic input variable :ref:`mietstufe <mietstufe>`. haushaltsgröße See :func:`haushaltsgröße`. hh_id See basic input variable :ref:`hh_id <hh_id>`. kaltmiete_m_hh See basic input variable :ref:`kaltmiete_m_hh <kaltmiete_m_hh>`. tax_unit_share See :func:`tax_unit_share`. wohngeld_min_miete See :func:`wohngeld_min_miete`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ data = [ wohngeld_params["max_miete"][hh_größe][ms] + wohngeld_params["heizkosten_zuschuss"][hh_größe] if hh_größe <= 5 else wohngeld_params["max_miete"][5][ms] + (wohngeld_params["max_miete"]["5plus"][ms] * (hh_größe - 5)) + wohngeld_params["heizkosten_zuschuss"][5] + wohngeld_params["heizkosten_zuschuss"]["5plus"] * (hh_größe - 5) for hh_größe, ms in zip(haushaltsgröße, mietstufe) ] out = ( np.clip(data, a_min=None, a_max=hh_id.replace(kaltmiete_m_hh)) * tax_unit_share ).clip(lower=wohngeld_min_miete) return out
def gemeinsam_veranlagt(tu_id: IntSeries, anz_erwachsene_tu: IntSeries) -> BoolSeries: """Check if the tax unit consists of two wage earners. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. anz_erwachsene_tu Return of :func:`anz_erwachsene_tu`. Returns ------- BoolSeries indicating two wage earners in tax unit. """ return tu_id.replace(anz_erwachsene_tu) == 2
def kinderzuschlag_kaltmiete_m(hh_id: IntSeries, kaltmiete_m_hh: FloatSeries, tax_unit_share: FloatSeries) -> FloatSeries: """Calculate costs of living without heating costs. Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. kaltmiete_m_hh See basic input variable :ref:`kaltmiete_m_hh <kaltmiete_m_hh>`. tax_unit_share See :func:`tax_unit_share`. Returns ------- """ return hh_id.replace(kaltmiete_m_hh) * tax_unit_share
def pflegev_zusatz_kinderlos(hat_kinder: BoolSeries, alter: IntSeries) -> BoolSeries: """ Create boolean Series indicating addtional care insurance contribution for childless individuals. Parameters ---------- hat_kinder See basic input variable :ref:`hat_kinder <hat_kinder>`. alter See basic input variable :ref:`alter <alter>`. Returns ------- """ # Todo: No hardcoded 22. return ~hat_kinder & alter.gt(22)
def kinderzuschlag_heizkost_m(hh_id: IntSeries, heizkosten_m_hh: FloatSeries, tax_unit_share: FloatSeries) -> FloatSeries: """Calculate costs of heating. Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. heizkosten_m_hh See basic input variable :ref:`heizkosten_m_hh <heizkosten_m_hh>`. tax_unit_share See :func:`tax_unit_share`. Returns ------- """ return hh_id.replace(heizkosten_m_hh) * tax_unit_share
def wohngeld_eink( tu_id: IntSeries, haushaltsgröße: IntSeries, wohngeld_eink_abzüge: FloatSeries, wohngeld_abzüge_tu: FloatSeries, wohngeld_brutto_eink_tu: FloatSeries, wohngeld_sonstiges_eink_tu: FloatSeries, wohngeld_params: dict, ) -> FloatSeries: """Calculate final income relevant for calculation of housing benefit. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. haushaltsgröße See :func:`haushaltsgröße`. wohngeld_eink_abzüge See :func:`wohngeld_eink_abzüge`. wohngeld_abzüge_tu See :func:`wohngeld_abzüge_tu`. wohngeld_brutto_eink_tu See :func:`wohngeld_brutto_eink_tu`. wohngeld_sonstiges_eink_tu See :func:`wohngeld_sonstiges_eink_tu`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ wohngeld_eink_abzüge_tu = wohngeld_eink_abzüge.groupby(tu_id).sum() vorläufiges_eink = (1 - wohngeld_abzüge_tu) * (wohngeld_brutto_eink_tu + wohngeld_sonstiges_eink_tu - wohngeld_eink_abzüge_tu) unteres_eink = haushaltsgröße.clip(upper=12).replace( wohngeld_params["min_eink"]) return tu_id.replace(vorläufiges_eink).clip(lower=unteres_eink)
def eink_anr_frei_ab_10_2005( hh_id: IntSeries, bruttolohn_m: FloatSeries, kinder_in_hh: BoolSeries, arbeitsl_geld_2_params: dict, ) -> FloatSeries: """Calcualte share of income, which remains to the individual sinc 10/2005. Parameters ---------- hh_id See basic input variable :ref:`hh_id <hh_id>`. bruttolohn_m See basic input variable :ref:`bruttolohn_m <bruttolohn_m>`. kinder_in_hh See :func:`kinder_in_h`. arbeitsl_geld_2_params See params documentation :ref:`arbeitsl_geld_2_params <arbeitsl_geld_2_params>`. Returns ------- """ out = bruttolohn_m * 0 kinder_in_hh_individual = hh_id.replace(kinder_in_hh).astype(bool) out.loc[kinder_in_hh_individual] = piecewise_polynomial( x=bruttolohn_m.loc[kinder_in_hh_individual], thresholds=arbeitsl_geld_2_params["eink_anr_frei_kinder"]["thresholds"], rates=arbeitsl_geld_2_params["eink_anr_frei_kinder"]["rates"], intercepts_at_lower_thresholds=arbeitsl_geld_2_params["eink_anr_frei_kinder"][ "intercepts_at_lower_thresholds" ], ) out.loc[~kinder_in_hh_individual] = piecewise_polynomial( x=bruttolohn_m.loc[~kinder_in_hh_individual], thresholds=arbeitsl_geld_2_params["eink_anr_frei"]["thresholds"], rates=arbeitsl_geld_2_params["eink_anr_frei"]["rates"], intercepts_at_lower_thresholds=arbeitsl_geld_2_params["eink_anr_frei"][ "intercepts_at_lower_thresholds" ], ) return out
def arbeitsl_geld_m( tu_id: IntSeries, anz_kinder_tu: IntSeries, berechtigt_für_arbeitsl_geld: BoolSeries, proxy_eink_vorj_arbeitsl_geld: FloatSeries, arbeitsl_geld_params: dict, ) -> FloatSeries: """Calculate unemployment benefit. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. anz_kinder_tu See :func:`anz_kinder_tu`. berechtigt_für_arbeitsl_geld See :func:`berechtigt_für_arbeitsl_geld`. proxy_eink_vorj_arbeitsl_geld See :func:`proxy_eink_vorj_arbeitsl_geld`. arbeitsl_geld_params See params documentation :ref:`arbeitsl_geld_params <arbeitsl_geld_params>`. Returns ------- """ arbeitsl_geld_satz = (tu_id.replace(anz_kinder_tu) == 0).replace( { True: arbeitsl_geld_params["arbeitsl_geld_satz_ohne_kinder"], False: arbeitsl_geld_params["arbeitsl_geld_satz_mit_kindern"], } ) arbeitsl_geld_m = berechtigt_für_arbeitsl_geld.astype(float) * 0 arbeitsl_geld_m[berechtigt_für_arbeitsl_geld] = ( proxy_eink_vorj_arbeitsl_geld * arbeitsl_geld_satz ) return arbeitsl_geld_m
def sonderausgaben_ab_2012( betreuungskost_m: FloatSeries, tu_id: IntSeries, kind: BoolSeries, anz_erwachsene_tu: IntSeries, eink_st_abzuege_params: dict, ) -> FloatSeries: """Calculate sonderausgaben for childcare since 2012. We follow 10 Abs.1 Nr. 5 EStG. You can details here https://www.buzer.de/s1.htm?a=10&g=estg. Parameters ---------- betreuungskost_m See basic input variable :ref:`betreuungskost_m <betreuungskost_m>`. tu_id See basic input variable :ref:`tu_id <tu_id>`. kind See basic input variable :ref:`kind <kind>`. eink_st_abzuege_params See params documentation :ref:`eink_st_abzuege_params <eink_st_abzuege_params>`. anz_erwachsene_tu See :func:`anz_erwachsene_tu`. Returns ------- """ erwachsene_in_tu = tu_id.replace(anz_erwachsene_tu) abziehbare_betreuungskosten = (12 * betreuungskost_m).clip( upper=eink_st_abzuege_params["kinderbetreuungskosten_abz_maximum"]) berechtigte_kinder = kind.groupby(tu_id).transform(sum) out = (berechtigte_kinder * abziehbare_betreuungskosten * eink_st_abzuege_params["kinderbetreuungskosten_abz_anteil"] ) / erwachsene_in_tu out.loc[kind] = 0 return out
def zu_verst_eink_kein_kinderfreib_tu( sum_brutto_eink: FloatSeries, vorsorge: FloatSeries, sonderausgaben: FloatSeries, behinderungsgrad_pauschbetrag: FloatSeries, alleinerziehend_freib_tu: FloatSeries, altersfreib: FloatSeries, tu_id: IntSeries, ) -> FloatSeries: """Calculate taxable income without child allowance. Parameters ---------- sum_brutto_eink See :func:`sum_brutto_eink`. vorsorge See :func:`vorsorge`. sonderausgaben See :func:`sonderausgaben`. behinderungsgrad_pauschbetrag See :func:`behinderungsgrad_pauschbetrag`. alleinerziehend_freib_tu See :func:`alleinerziehend_freib_tu`. altersfreib See :func:`altersfreib`. tu_id See basic input variable :ref:`tu_id <tu_id>`. Returns ------- """ out = (sum_brutto_eink - vorsorge - sonderausgaben - behinderungsgrad_pauschbetrag - tu_id.replace(alleinerziehend_freib_tu) - altersfreib).clip(lower=0) return out.groupby(tu_id).sum()
def kindergeld_m_ab_1997( beantrage_kind_freib_tu: BoolSeries, kindergeld_m_basis: FloatSeries, tu_id: IntSeries, ) -> FloatSeries: """Kindergeld calculation since 1997. Parameters ---------- beantrage_kind_freib_tu See :func:`beantrage_kind_freib_tu`. kindergeld_m_basis See :func:`kindergeld_m_basis`. tu_id See basic input variable :ref:`tu_id <tu_id>`. Returns ------- """ beantrage_kind_freib = tu_id.replace(beantrage_kind_freib_tu) out = kindergeld_m_basis out.loc[beantrage_kind_freib] = 0 return out
def kinderbonus_m( beantrage_kind_freib_tu: BoolSeries, kinderbonus_m_basis: FloatSeries, tu_id: IntSeries, ) -> FloatSeries: """Calculate Kinderbonus (one-time payment, non-allowable against transfer payments). Parameters ---------- beantrage_kind_freib_tu See :func:`beantrage_kind_freib_tu`. kinderbonus_m_basis See :func:`kinderbonus_m_basis`. tu_id See basic input variable :ref:`tu_id <tu_id>`. Returns ------- """ beantrage_kind_freib = tu_id.replace(beantrage_kind_freib_tu) out = kinderbonus_m_basis out.loc[beantrage_kind_freib] = 0 return out
def unterhaltsvors_m( tu_id: IntSeries, alleinerziehend: BoolSeries, alter: IntSeries, unterhaltsvorschuss_eink_tu: FloatSeries, unterhalt_params: dict, kindergeld_params: dict, ) -> FloatSeries: """Calculate advance on alimony payment(Unterhaltsvorschuss). Single Parents get alimony payments for themselves and for their child from the ex partner. If the ex partner is not able to pay the child alimony, the government pays the child alimony to the mother (or the father, if he has the kids) The amount is specified in §1612a BGB and, ultimately, in Mindesunterhaltsverordnung. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. alleinerziehend See basic input variable :ref:`alleinerziehend <alleinerziehend>`. alter See basic input variable :ref:`alter <alter>`. unterhaltsvorschuss_eink_tu See :func:`unterhaltsvorschuss_eink_tu`. unterhalt_params See params documentation :ref:`unterhalt_params <unterhalt_params>`. kindergeld_params See params documentation :ref:`kindergeld_params <kindergeld_params>`. Returns ------- """ # Initialize output Series out = tu_id * 0 # The right-hand-side variable is aggregated by tax units whereas we need personal # ids on the left-hand-side. Index with tax unit identifier for expansion and remove # index because it is unterhaltsvorschuss_eink = tu_id.replace(unterhaltsvorschuss_eink_tu) conditions = [ (alter < 6) & alleinerziehend, (alter >= 6) & (alter < 12) & alleinerziehend, # Older kids get it only if the parent has income > 600€. (alter >= 12) & (alter < 18) & alleinerziehend & ( unterhaltsvorschuss_eink > unterhalt_params["unterhaltsvorschuss_mindesteinkommen"] ), ] choices = [ (unterhalt_params["mindestunterhalt"][6] - kindergeld_params["kindergeld"][1]), (unterhalt_params["mindestunterhalt"][12] - kindergeld_params["kindergeld"][1]), (unterhalt_params["mindestunterhalt"][17] - kindergeld_params["kindergeld"][1]), ] out[:] = np.ceil(np.select(conditions, choices)).astype(int) # TODO: Check against actual transfers return out
def wohnbedarf_eltern_anteil( tu_id: IntSeries, anz_kinder_tu: IntSeries, anz_erwachsene_tu: IntSeries, kinderzuschlag_params: dict, ) -> FloatSeries: """Calculate living needs broken down to the parents. Defined as parents' subsistence level on housing, divided by sum of subsistence level from parents and children. Parameters ---------- tu_id See basic input variable :ref:`tu_id <tu_id>`. anz_kinder_tu See :func:`anz_kinder_tu`. anz_erwachsene_tu See :func:`anz_erwachsene_tu`. kinderzuschlag_params See params documentation :ref:`kinderzuschlag_params <kinderzuschlag_params>`. Returns ------- """ kinder_in_tu = tu_id.replace(anz_kinder_tu) erwachsene_in_tu = tu_id.replace(anz_erwachsene_tu) conditions = [] choices = [] ex_min = kinderzuschlag_params["exmin"] adults_map = {1: "single", 2: "paare"} for n_adults in [1, 2]: for n_children in [1, 2, 3, 4]: condition = (kinder_in_tu == n_children) & (erwachsene_in_tu == n_adults) choice = ( ex_min["kosten_der_unterkunft"][adults_map[n_adults]] + ex_min["heizkosten"][adults_map[n_adults]] ) / ( ex_min["kosten_der_unterkunft"][adults_map[n_adults]] + ex_min["heizkosten"][adults_map[n_adults]] + ( n_children * ( ex_min["kosten_der_unterkunft"]["kinder"] + ex_min["heizkosten"]["kinder"] ) ) ) conditions.append(condition) choices.append(choice) condition = (kinder_in_tu >= 5) & (erwachsene_in_tu == n_adults) choice = ( ex_min["kosten_der_unterkunft"][adults_map[n_adults]] + ex_min["heizkosten"][adults_map[n_adults]] ) / ( ex_min["kosten_der_unterkunft"][adults_map[n_adults]] + ex_min["heizkosten"][adults_map[n_adults]] + ( 5 * ( ex_min["kosten_der_unterkunft"]["kinder"] + ex_min["heizkosten"]["kinder"] ) ) ) conditions.append(condition) choices.append(choice) # Add defaults. Is is really necessary or are the former conditions exhaustive? conditions.append(True) choices.append(1) anteil = pd.Series(index=tu_id.index, data=np.select(conditions, choices)) return anteil