Luokiteltu jakauma

Tämän artikkelin ohjelmakoodin ja tulosteet löydät GitHubista:

https://github.com/taanila/tilastoapu/blob/master/luokiteltu_jakauma.ipynb

Jos kopioit koodia itsellesi, niin kannattaa käyttää GitHubia. Tästä artikkelista kopioidut koodit eivät välttämättä toimi oikein (esimerkiksi sisennykset voivat kopioitua virheellisesti).

Oletan, että lukijalla on asennettuna Anaconda ja sen mukana tuleva Jupyter notebook.

Määrällisen muuttujan arvot kannattaa yleensä luokitella ennen frekvenssien laskemista. Pythonilla tämä sujuu pandas-ohjelmakirjaston cut-funktiolla.

Aluksi avaan Excel-muotoisen datan dataframeen:

import pandas as pd
df=pd.read_excel('http://taanila.fi/data1.xlsx', 
   sheet_name='Data')

Ennen ikä-muuttujan luokittelua tarkastelen ikää tunnuslukujen valossa:

df['ikä'].describe()

pyluoki1

Huomaan muun muassa, että nuorin on 20-vuotias ja vanhin 61-vuotias. Tältä pohjalta voin miettiä sopivia luokkarajoja. Määritän luokkarajat ja luokkien nimet:

bins = [20, 30, 40, 50, 62]
group_names = ['20-29', '30-39', '40-49', '50-']

Tämän jälkeen määritteleen aineistoon uudet muuttujat (sarakkeet), joiden nimiksi annan luokkarajat ja ikäluokka. Jos right=False niin alarajat kuuluvat luokkaan, mutta ylärajat eivät kuulu. Tämän otin huomioon jo luokkarajojen määrittelyssä asettamalla ylimmän rajan 62-vuoden kohdalle.

df['luokkarajat'] = pd.cut(df['ikä'], bins, right = False)
df['ikäluokka'] = pd.cut(df['ikä'], bins, labels = 
   group_names, right = False)

Voin taulukoida luokkarajat ja niiden frekvenssit crosstab-toiminnolla:

pd.crosstab(df['luokkarajat'],'lkm')

pyluoki3

Luokkarajoissa käytetään matematiikasta tuttua merkintätapaa: hakasulkeen vieressä oleva luku kuuluu luokkaan, mutta kaarisulkeen vieressä oleva luku ei kuulu luokkaan.

Seuraavassa taulukoin ikäluokka-muuttujan frekvenssiprosentit, korvaan vasemman ylänurkan col_0-nimen tyhjällä merkkijonolla ja muotoilen prosenttiluvut yhden desimaalin tarkkuuteen:

df1 = pd.crosstab(df['ikäluokka'], 'lkm', normalize = 
   'columns')
df1.columns.name = ''
df1.style.format('{:.1%}')

pyluoki2

Aiemmissa artikkeleissani en ole tainnutkaan määritellä omia funktioita. Nyt korjaan sen puutteen ja määrittelen funktion, joka osaa laskea funktiolle annetuista lähtötiedoista (group) lukumäärän, minimin, maksimin ja keskiarvon. Funktion määrittely aloitetaan sanalla def:

def get_stats(group):
   return {'min': group.min(), 'max': group.max(), 'lkm': 
      group.count(), 'keskiarvo': group.mean()}

Itse määrittelemääni funktiota käyttäen voin kätevästi laskea tunnuslukuja ikäluokittain. Groupby ryhmittelee määrittelemieni ikäluokkien mukaan.

df2 = df['palkka'].groupby(df['ikäluokka']).
   apply(get_stats).unstack()

Unstack() hoitaa tunnuslukujen tulostuksen vierekkäin.

Tunnusluvut tulostuvat aakkosjärjestyksessä keskiarvo, lkm, max, min, jollen vartavasten määritä haluamaani järjestystä. Desimaalien määräksi säädän 0.

df2 = df2[['lkm', 'min', 'max', 'keskiarvo']] 
df2.style.format('{:.0f}')

Lopputulos näyttää seuraavalta:

pyluoki4

Mainokset