Ristiintaulukointi – crosstab()

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

https://github.com/taanila/tilastoapu/blob/master/ristiintaulukointi.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.

Edellisessä artikkelissani Frekvenssitaulukot Exceliin kerroin miten lasket Pythonilla frekvenssitaulukoita. Tässä artikkelissa jatkan frekvenssien laskemista crosstab-toiminnolla, mutta laajennan tarkastelua frekvenssitaulukoista ristiintaulukointeihin.

Aluksi otan käyttöön pandas-kirjaston ja avaan Excel-muotoisen datan dataframeen.

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

Ristiintaulukointi lukumäärinä

Seuraavaksi lasken ristiintaulukoinnin sukupuolen ja koulutuksen välille. Lisäasetuksella margins=True saan taulukkoon rivi- ja sarakesummat.

df1 = pd.crosstab(df['sukup'], df['koulutus'], margins = True)

Koska aineistossani sukupuolen ja koulutuksen arvot ovat numeroina, niin annan niille selväkieliset nimet:

df1.index = ['Mies', 'Nainen', 'Yhteensä']
df1.columns = ['Peruskoulu', '2. aste', 'Korkeakoulu', 
   'Ylempi korkeakoulu', 'Yhteensä']

Huomaa, että myös rivi- ja sarakesummat täytyy nimetä samalla kuin muuttujien arvot (Yhteensä).

Lopuksi tulostan ristiintaulukoinnin näkyviin komennolla df1.

df13

Ristiintaulukointi prosentteina

Voin laskea ristiintaulukointiin prosentit lisäasetuksella normalize=’columns’ (prosentit sarakkeiden summista):

df2 = pd.crosstab(df['johto'], df['sukup'], 
   margins = True, normalize = 'columns')

Tässäkin annan muuttujan arvoille selväkieliset nimet:

df2.columns = ['Mies', 'Nainen', 'Yhteensä']
df2.index = ['Erittäin tyytymätön', 'Tyytymätön', 
   'Ei tyytymätön eikä tyytyväinen', 'Tyytyväinen', 
   'Erittäin tyytyväinen']

Prosentit näkyvät desimaalimuodossa ellen varta vasten vaihda muotoilua:

df2.style.format('{:.1%}')

Lopputulos näyttää seuraavalta:

df14

Huomaa, että summariviä ei näytetä sarakeprosentteja käytettäessä.

Useampia muuttujia ristiintaulukointiin

Voin korvata muuttujien arvot selväkielisillä nimillä etukäteen itse aineistoon:

df['sukup'].replace([1, 2], ['Mies', 'Nainen'], inplace = True)
df['perhe'].replace([1,2], ['Perheetön', 'Perheellinen'], 
   inplace = True)

Ristiintaulukointiin voin ottaa mukaan useampiakin muuttujia. Seuraavassa otan sarakemuuttujiksi sekä sukupuolen että perheen.

df3 = pd.crosstab(df['johtoon'], [df['sukup'], df['perhe']], 
   margins = True)

Voin nimetä rivi- ja sarakeotsikoita uudelleen:

df3 = df3.rename(columns = {'All': 'Yhteensä'})
df3 = df3.rename(index = {'All': 'Yhteensä'})
df3

df15

Useita ristiintaulukointeja for-silmukalla

Ristiintaulukointeja ei tarvitse laskea yksi kerrallaan. For-silmukalla voin tuottaa kaikki ristiintaulukoinnit kerralla. Harkitsen toki etukäteen mistä kaikesta ristiintaulukointi kannattaa laskea.

Seuraavassa muodostan osa-aineiston niistä muuttujista, joita haluan käyttää ristiintaulukointeihin:

columns = ['sukup', 'perhe', 'koulutus', 'johto', 'työtov',
   'työymp', 'palkkat', 'työteht']
df_osa = pd.DataFrame(df, columns = columns)

Seuraavassa teen kaikki mahdolliset ristiintaulukoinnit sukupuolen kanssa. For-silmukalla voin käydä läpi kaikki df_osa-dataframen muuttujat. Sukupuolta ei voi ristiintaulukoida itsensä kanssa. Tämän takia tarkistan if-lauseella, onko var erisuuri kuin sukupuoli?

for var in df_osa:
   if var != 'sukup':
      df4 = pd.crosstab(df_osa[var], df_osa['sukup'])
      print(df4)

Katsotaan vielä viimeisenä esimerkkinä, miten aineiston kaikki kahden muuttujan väliset ristiintaulukoinnit lasketaan ja kirjoitetaan Exceliin.

writer = pd.ExcelWriter('ristit.xlsx', engine = 'xlsxwriter')
rivi = 0
for var1 in df_osa:
   for var2 in df_osa:
      if var1 != var2:
         df5 = pd.crosstab(df_osa[var1], df_osa[var2])
         df5.to_excel(writer, sheet_name = 'Ristiintaulukoinnit', 
            startrow=rivi)
         rivi = rivi + df5.shape[0] + 2

Tallennan Excel-tiedoston:

writer.save()

Seuraavassa artikkelissani Luokiteltu jakauma luokittelen muuttujan arvot (esimerkiksi palkat palkkaluokiksi) ennen frekvenssien ja tunnuslukujen laskemista.

Mainokset