def enrich_with_personen_features(self, personen):
    'Add aggregated features relating to persons to the address dataframe. Uses the personen dataframe as input.'
    adres = self.data
    today = pd.to_datetime('today')
    personen['geboortedatum'] = pd.to_datetime(personen['geboortedatum'], errors='coerce')
    geboortedatum_mode = personen['geboortedatum'].mode()[0]
    personen['leeftijd'] = (today - personen['geboortedatum'])
    personen['leeftijd'] = personen['leeftijd'].apply((lambda x: (x.days / 365.25)))
    adres_ids = adres.adres_id
    personen_adres_ids = personen.ads_id_wa
    intersect = set(adres_ids).intersection(set(personen_adres_ids))
    inhabitant_locs = {}
    print('Now looping over all address ids that have a link with one or more inhabitants...')
    for (i, adres_id) in enumerate(intersect):
        if ((i % 1000) == 0):
            print(i)
        inhabitant_locs[adres_id] = personen_adres_ids[(personen_adres_ids == adres_id)]
    adres['aantal_personen'] = 0
    adres['aantal_vertrokken_personen'] = (- 1)
    adres['aantal_overleden_personen'] = (- 1)
    adres['aantal_niet_uitgeschrevenen'] = (- 1)
    adres['leegstand'] = True
    adres['leeftijd_jongste_persoon'] = (- 1.0)
    adres['leeftijd_oudste_persoon'] = (- 1.0)
    adres['aantal_kinderen'] = 0
    adres['percentage_kinderen'] = (- 1.0)
    adres['aantal_mannen'] = 0
    adres['percentage_mannen'] = (- 1.0)
    adres['gemiddelde_leeftijd'] = (- 1.0)
    adres['stdev_leeftijd'] = (- 1.0)
    adres['aantal_achternamen'] = 0
    adres['percentage_achternamen'] = (- 1.0)
    for i in range(1, 8):
        adres[f'gezinsverhouding_{i}'] = 0
        adres[f'percentage_gezinsverhouding_{i}'] = 0.0
    print('Now looping over all rows in the adres dataframe in order to add person information...')
    for i in adres.index:
        if ((i % 1000) == 0):
            print(i)
        row = adres.iloc[i]
        adres_id = row['adres_id']
        try:
            inhab_locs = inhabitant_locs[adres_id].keys()
            inhab = personen.loc[inhab_locs]
            aantal_vertrokken_personen = sum(inhab['vertrekdatum_adam'].notnull())
            aantal_overleden_personen = sum(inhab['overlijdensdatum'].notnull())
            aantal_niet_uitgeschrevenen = len(inhab[(inhab['vertrekdatum_adam'].notnull() | inhab['overlijdensdatum'].notnull())])
            adres['aantal_vertrokken_personen'] = aantal_vertrokken_personen
            adres['aantal_overleden_personen'] = aantal_overleden_personen
            adres['aantal_niet_uitgeschrevenen'] = aantal_niet_uitgeschrevenen
            if (len(inhab) > aantal_niet_uitgeschrevenen):
                adres['leegstand'] = False
            aantal_personen = len(inhab)
            adres.at[(i, 'aantal_personen')] = aantal_personen
            leeftijd_jongste_persoon = min(inhab['leeftijd'])
            adres.at[(i, 'leeftijd_jongste_persoon')] = leeftijd_jongste_persoon
            leeftijd_oudste_persoon = max(inhab['leeftijd'])
            adres.at[(i, 'leeftijd_oudste_persoon')] = leeftijd_oudste_persoon
            aantal_kinderen = sum((inhab['leeftijd'] < 18))
            adres.at[(i, 'aantal_kinderen')] = aantal_kinderen
            adres.at[(i, 'percentage_kinderen')] = (aantal_kinderen / aantal_personen)
            aantal_mannen = sum((inhab.geslacht == 'M'))
            adres.at[(i, 'aantal_mannen')] = aantal_mannen
            adres.at[(i, 'percentage_mannen')] = (aantal_mannen / aantal_personen)
            gemiddelde_leeftijd = inhab.leeftijd.mean()
            adres.at[(i, 'gemiddelde_leeftijd')] = gemiddelde_leeftijd
            stdev_leeftijd = inhab.leeftijd.std()
            adres.at[(i, 'stdev_leeftijd')] = (stdev_leeftijd if (aantal_personen > 1) else 0)
            aantal_achternamen = inhab.naam.nunique()
            adres.at[(i, 'aantal_achternamen')] = aantal_achternamen
            adres.at[(i, 'percentage_achternamen')] = (aantal_achternamen / aantal_personen)
            gezinsverhouding = inhab.gezinsverhouding.value_counts()
            for key in gezinsverhouding.keys():
                val = gezinsverhouding[key]
                adres.at[(i, f'gezinsverhouding_{key}')] = val
                adres.at[(i, f'percentage_gezinsverhouding_{key}')] = (val / aantal_personen)
        except (KeyError, ValueError) as e:
            pass
    print('...done!')
    self.data = adres
    self.version += '_personen'
    self.save()
    print('The adres dataset is now enriched with personen data.')
Add aggregated features relating to persons to the address dataframe. Uses the personen dataframe as input.
def enrich_with_personen_features(self, personen):
    
    adres = self.data
    today = pd.to_datetime('today')
    personen['geboortedatum'] = pd.to_datetime(personen['geboortedatum'], errors='coerce')
    geboortedatum_mode = personen['geboortedatum'].mode()[0]
    personen['leeftijd'] = (today - personen['geboortedatum'])
    personen['leeftijd'] = personen['leeftijd'].apply((lambda x: (x.days / 365.25)))
    adres_ids = adres.adres_id
    personen_adres_ids = personen.ads_id_wa
    intersect = set(adres_ids).intersection(set(personen_adres_ids))
    inhabitant_locs = {}
    print('Now looping over all address ids that have a link with one or more inhabitants...')
    for (i, adres_id) in enumerate(intersect):
        if ((i % 1000) == 0):
            print(i)
        inhabitant_locs[adres_id] = personen_adres_ids[(personen_adres_ids == adres_id)]
    adres['aantal_personen'] = 0
    adres['aantal_vertrokken_personen'] = (- 1)
    adres['aantal_overleden_personen'] = (- 1)
    adres['aantal_niet_uitgeschrevenen'] = (- 1)
    adres['leegstand'] = True
    adres['leeftijd_jongste_persoon'] = (- 1.0)
    adres['leeftijd_oudste_persoon'] = (- 1.0)
    adres['aantal_kinderen'] = 0
    adres['percentage_kinderen'] = (- 1.0)
    adres['aantal_mannen'] = 0
    adres['percentage_mannen'] = (- 1.0)
    adres['gemiddelde_leeftijd'] = (- 1.0)
    adres['stdev_leeftijd'] = (- 1.0)
    adres['aantal_achternamen'] = 0
    adres['percentage_achternamen'] = (- 1.0)
    for i in range(1, 8):
        adres[f'gezinsverhouding_{i}'] = 0
        adres[f'percentage_gezinsverhouding_{i}'] = 0.0
    print('Now looping over all rows in the adres dataframe in order to add person information...')
    for i in adres.index:
        if ((i % 1000) == 0):
            print(i)
        row = adres.iloc[i]
        adres_id = row['adres_id']
        try:
            inhab_locs = inhabitant_locs[adres_id].keys()
            inhab = personen.loc[inhab_locs]
            aantal_vertrokken_personen = sum(inhab['vertrekdatum_adam'].notnull())
            aantal_overleden_personen = sum(inhab['overlijdensdatum'].notnull())
            aantal_niet_uitgeschrevenen = len(inhab[(inhab['vertrekdatum_adam'].notnull() | inhab['overlijdensdatum'].notnull())])
            adres['aantal_vertrokken_personen'] = aantal_vertrokken_personen
            adres['aantal_overleden_personen'] = aantal_overleden_personen
            adres['aantal_niet_uitgeschrevenen'] = aantal_niet_uitgeschrevenen
            if (len(inhab) > aantal_niet_uitgeschrevenen):
                adres['leegstand'] = False
            aantal_personen = len(inhab)
            adres.at[(i, 'aantal_personen')] = aantal_personen
            leeftijd_jongste_persoon = min(inhab['leeftijd'])
            adres.at[(i, 'leeftijd_jongste_persoon')] = leeftijd_jongste_persoon
            leeftijd_oudste_persoon = max(inhab['leeftijd'])
            adres.at[(i, 'leeftijd_oudste_persoon')] = leeftijd_oudste_persoon
            aantal_kinderen = sum((inhab['leeftijd'] < 18))
            adres.at[(i, 'aantal_kinderen')] = aantal_kinderen
            adres.at[(i, 'percentage_kinderen')] = (aantal_kinderen / aantal_personen)
            aantal_mannen = sum((inhab.geslacht == 'M'))
            adres.at[(i, 'aantal_mannen')] = aantal_mannen
            adres.at[(i, 'percentage_mannen')] = (aantal_mannen / aantal_personen)
            gemiddelde_leeftijd = inhab.leeftijd.mean()
            adres.at[(i, 'gemiddelde_leeftijd')] = gemiddelde_leeftijd
            stdev_leeftijd = inhab.leeftijd.std()
            adres.at[(i, 'stdev_leeftijd')] = (stdev_leeftijd if (aantal_personen > 1) else 0)
            aantal_achternamen = inhab.naam.nunique()
            adres.at[(i, 'aantal_achternamen')] = aantal_achternamen
            adres.at[(i, 'percentage_achternamen')] = (aantal_achternamen / aantal_personen)
            gezinsverhouding = inhab.gezinsverhouding.value_counts()
            for key in gezinsverhouding.keys():
                val = gezinsverhouding[key]
                adres.at[(i, f'gezinsverhouding_{key}')] = val
                adres.at[(i, f'percentage_gezinsverhouding_{key}')] = (val / aantal_personen)
        except (KeyError, ValueError) as e:
            pass
    print('...done!')
    self.data = adres
    self.version += '_personen'
    self.save()
    print('The adres dataset is now enriched with personen data.')