vrijdag 20 december 2019

Profiling van dataframe

met het handje

# ==> Analyse
df1.info()
df1.nunique()
print(df1.describe())


df1[df1['VALID_BSN'].isnull()]
df1[df1['VALID_BSN']=='0'].info()


df1[df1['BSN'].isnull()]
df1[df1['BSN']=='999999999']


dubbele records
df1[df1.duplicated(subset=None)]





df1=xls_file.parse(0,skiprows=0,dtype=str)

df1=df1.astype({'VD_Ingangsdatum': 'datetime64', 'VD_Einddatum': 'datetime64'})

dictVeldnamen={'Valid_BSN':'VALID_BSN','LR_BSN': 'BSN', 'VD_Ingangsdatum': 'BEGIN_DATUM','VD_Einddatum':'EIND_DATUM','Code_Bron': 'CODE_BRON'}

df1.rename(columns=dictVeldnamen,inplace='true')

df1.drop_duplicates(subset=None, keep='last', inplace=True)


alternatief pandas-profiling 

# importing required packages
import pandas as pd
import pandas_profiling
import numpy as np

# importing the data
df = pd.read_csv('/Users/lukas/Downloads/titanic/train.csv')

pandas_profiling.ProfileReport(df)

Hoe kan je makkelijk een dataframe groeperen en per groep bewerkingen uitvoeren

Hoe kan je makkelijk een dataframe groeperen en per groep bewerkingen uitvoeren



def func1(name,group):
    print(group)

df1.groupby(['BSN']).apply(lambda x: func1(x.name,x))

def func2(name,group):
    print(name)

df1.groupby(['BSN','CODE_VOORZIENING']).apply(lambda x: func2(x.name,x))


voorbeeld

def checkOverlapPerGroepering(tgroep,dfx):
    global myresult
    # Maak een set
    dfx['myrange']=dfx.apply(lambda x: set(x['myrange']),axis=1)
 #   ==> ga bepalen er een join is tussen de myrange records van de bsn
    geenoverlap=True
    lstbsnoverlap=[]  
    for i in range(len(dfx)-1):
        geenoverlap=dfx['myrange'].iloc[i].isdisjoint(dfx['myrange'].iloc[i+1]) &  geenoverlap
    trecord={'groep':str(tgroep),'geenoverlap': geenoverlap}
    myresult=myresult.append(trecord,ignore_index=True)
   

>>>>> main 2>>>>>

myresult = pd.DataFrame(columns =['groep', 'geenoverlap'])
df1.groupby(['BSN']).apply(lambda x: checkOverlapPerGroepering(x.name,x))
df1.groupby(['BSN','CODE_VOORZIENING']).apply(lambda x: checkOverlapPerGroepering(x.name,x))

date datetime handigheidjes


hoe maak je van een String een datum  formaat  

  • convert the string to datetime with strptime()
  • converrt the datetime to date

dt.datetime.strptime('2016-07-15 00:00:00', '%Y-%m-%d %H:%M:%S').date())



Hoe maak je van een datum een string

date_time = now.strftime("%m/%d/%Y, %H:%M:%S")

hoe maak je een lijst van datums gebaseerd op begin en einddatum

Gebruik de pd.date_range functie

voorb
spelingrechts=7
spelinglinks=7

#Genereer per regel alle lijst met alle datumvelden op
df1['myrange']=df1.apply(lambda x: pd.date_range(x['BEGIN_DATUM']+timedelta(days=spelinglinks),x['EIND_DATUM']-timedelta(days=spelingrechts), freq='D'),axis=1)




Convert Datetimeindex to Index using specified date_format.

df1['myrange']=df1['myrange'].map(lambda x: x.strftime("%Y/%m/%d"))

voorbeeld: hoe berekenen je kosten per dag gebaseerd op begin en einddatum

# -*- coding: utf-8 -*-
"""
Created on Thu Dec 19 13:47:28 2019

@author: wagene002
"""

#https://stackoverflow.com/questions/43832484/expanding-a-dataframe-based-on-start-and-end-columns-speed
import numpy as np
import pandas as pd
from datetime import timedelta
import datetime as dt


df = pd.DataFrame()
df['BEGIN_DATUM'] = [dt.datetime(2010, 12, 31), dt.date(2013, 4, 5)]
df['EIND_DATUM'] = [dt.date(2011, 1, 3), dt.date(2016, 12, 12)]
df['country'] = ['US', 'EU']
df['letter'] = ['a', 'b']
df['bedrag'] = ['1200.0','44']
df['bedrag']= df['bedrag'].apply(lambda x : float(x))

df['diffdagen'] =((df['EIND_DATUM']-df['BEGIN_DATUM']) / np.timedelta64(1, 'D')).astype('int') + 1
 !!!!
alternatieve manier:  df['diffdagen'] = df.apply(lambda x: (x['EIND_DATUM']-x['BEGIN_DATUM']).days,axis=1)
 !!!!

df['dagbedrag'] = df['bedrag']/  df['diffdagen']


cols = list(df.columns)

#bepaal per regel het data id
df['data_id'] = np.arange(0, len(df))
df['BEGIN_JAAR']=df['BEGIN_DATUM'].map(lambda x:x.year)
df['EIND_JAAR']=df['EIND_DATUM'].map(lambda x:x.year)

#stop data in series
data_id = df['data_id']
start1 = df['BEGIN_JAAR']
end1 = df['EIND_JAAR']

#diff = ((end-start) / np.timedelta64(1, 'Y')).astype('int') + 1
#bepaal hoeveel jaren er voorkomen in een regel
diff = (end1-start1) + 1
#genereer het data_id uit per aantal gevonden jaren
repeated_id = np.repeat(data_id, diff)

time_df = pd.DataFrame(data={'data_id': repeated_id})
time_df = pd.merge(left=time_df, right=df[['data_id', 'BEGIN_JAAR','EIND_JAAR']], on=['data_id'])


time_df['year_id'] = np.arange(0, len(time_df))

min_year_id = time_df.groupby('data_id')['year_id'].min().reset_index().rename(columns={'year_id': 'min_year_id'})
time_df = pd.merge(left=time_df, right=min_year_id, on=['data_id'])
#years_to_add = (time_df['year_id'] - time_df['min_year_id']) * np.timedelta64(1, 'Y')
years_to_add = (time_df['year_id'] - time_df['min_year_id'])
time_df['JAARTAL'] = time_df['BEGIN_JAAR'] + years_to_add

#time_df = time_df[time_df['JAARTAL'].dt.dayofweek < 5]

dfuit = pd.merge(left=df, right=time_df[['data_id', 'JAARTAL']], on=['data_id'])


def fBepaalAantalDagen(tseries):
    ndagen=0
    year_start=dt.date(tseries['JAARTAL'], 1, 1)
    year_end=dt.date(tseries['JAARTAL'], 12, 31)
    #startdatum ligt in het jaar zelf
    if tseries['BEGIN_JAAR']== tseries['JAARTAL'] :
        #start in jaar en einddatum ligt in jaren erna
        if tseries['EIND_JAAR'] > tseries['JAARTAL'] :
            #alleen de dagen van begindatum tot 31-12 berekeen
            ndagen=  ((year_end-tseries['BEGIN_DATUM']).days + 1)
        #start en eind liggen in zelfde jaar
        elif tseries['EIND_JAAR'] == tseries['JAARTAL']:
            ndagen=  ((tseries['EIND_DATUM']-tseries['BEGIN_DATUM']).days + 1)
    #startdatum ligt voor het jaar zelf       
    if (tseries['BEGIN_JAAR'] < tseries['JAARTAL']) & (tseries['EIND_JAAR'] >=  tseries['JAARTAL']) :   
       # start ligt voor het jaar en eind ligt na het jaar
        if tseries['EIND_JAAR'] > tseries['JAARTAL'] :
            #tel hele jaar
            ndagen= ((year_end-year_start).days + 1)
        # start ligt voor jaar en einde ligt in het jaar
        elif tseries['EIND_JAAR'] == tseries['JAARTAL']:
            #tel dagen vanaf 1-1 tm einde
            ndagen=  ((tseries['EIND_DATUM']-year_start).days + 1)
    return ndagen


dfuit['aantal_dag_in_jaar']=dfuit.apply(lambda x: fBepaalAantalDagen(x),axis=1)




dfuit = dfuit[['JAARTAL']+cols]

t

Datums bepalen adhv begin en einddatum in Dataframe

Voorbeeld op losse velden  ####################################################################### # import necessary packages from datetime...