Ristiintaulukointi - crosstab()

In [1]:
import pandas as pd
df = pd.read_excel('http://taanila.fi/data1.xlsx')
In [2]:
#ristiintaulukointi sujuu crosstab-toiminnolla, margins=True tuottaa rivi- ja sarakesummat
df1 = pd.crosstab(df['sukup'], df['koulutus'], margins = True)

#sukupuolia on merkitty aineistossa numeroilla 1 ja 2; haluan niille oikeat nimet
df1.index = ['Mies', 'Nainen', 'Yhteensä']

#koulutusasteita on merkitty aineistossa numeroilla 1, 2, 3 ja 4; haluan niille oikeat nimet
df1.columns = ['Peruskoulu', '2. aste', 'Korkeakoulu', 'Ylempi korkeakoulu', 'Yhteensä']

df1
Out[2]:
Peruskoulu 2. aste Korkeakoulu Ylempi korkeakoulu Yhteensä
Mies 22 23 15 2 62
Nainen 5 7 7 0 19
Yhteensä 27 30 22 2 81
In [3]:
#normalize='columns' tuottaa lukumäärien sijasta prosentit sarakkeiden summista
df2 = pd.crosstab(df['johto'], df['sukup'], margins = True, normalize = 'columns')

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']

#ilman muotoilua prosentit näkyisivät desimaalimuodossa
(df2*100).style.format('{:.1f} %')
Out[3]:
Mies Nainen Yhteensä
Erittäin tyytymätön 11.1 % 0.0 % 8.5 %
Tyytymätön 23.8 % 5.3 % 19.5 %
Ei tyytymätön eikä tyytyväinen 36.5 % 36.8 % 36.6 %
Tyytyväinen 23.8 % 42.1 % 28.0 %
Erittäin tyytyväinen 4.8 % 15.8 % 7.3 %
In [4]:
#voin korvata muuttujan numeroarvot oikeilla nimillä myös itse aineistoon
df['sukup'].replace([1, 2], ['Mies', 'Nainen'], inplace = True)
df['perhe'].replace([1, 2], ['Perheetön', 'Perheellinen'], inplace = True)

#ristiintaulukointiin voin lisätä myös useampia muuttujia
df3 = pd.crosstab(df['johto'], [df['sukup'], df['perhe']], margins = True)

#voin nimetä uudelleen rivi (index)- ja sarakeotsikoita (columns)
df3 = df3.rename(columns = {'All': 'Yhteensä'})
df3 = df3.rename(index = {'All': 'Yhteensä'})

df3
Out[4]:
sukup Mies Nainen Yhteensä
perhe Perheellinen Perheetön Perheellinen Perheetön
johto
1 3 4 0 0 7
2 8 7 1 0 16
3 12 11 5 2 30
4 10 5 7 1 23
5 2 1 3 0 6
Yhteensä 35 28 16 3 82
In [5]:
#muodostan osa-aineiston df_osa, johon otan mukaan vain tietyt sarakkeet
columns = ['sukup', 'perhe', 'koulutus', 'johto', 'työtov',
        'työymp', 'palkkat', 'työteht']
df_osa = pd.DataFrame(df,columns = columns)

#käyn for-silmukalla läpi kaikki df_osa -dataframen muuttujat (sarakkeet)
#laskeen jokaiselle muuttujalle ristiintaulukoinnin sukupuolen kanssa
for var in df_osa:
    
    #tarkastan ettei var ole sukupuoli, koska en voi ristiintaulukoida muuttujaa itsensä kanssa
    if var != 'sukup':
        df4 = pd.crosstab(df_osa[var], df_osa['sukup'])
        print(df4)
sukup         Mies  Nainen
perhe                     
Perheellinen    35      16
Perheetön       28       3
sukup     Mies  Nainen
koulutus              
1.0         22       5
2.0         23       7
3.0         15       7
4.0          2       0
sukup  Mies  Nainen
johto              
1         7       0
2        15       1
3        23       7
4        15       8
5         3       3
sukup   Mies  Nainen
työtov              
2.0        3       0
3.0        9       7
4.0       27       8
5.0       23       4
sukup   Mies  Nainen
työymp              
1          9       0
2          7       2
3         27       3
4         15       8
5          5       6
sukup    Mies  Nainen
palkkat              
1          32       1
2          12       7
3          12       7
4           7       3
5           0       1
sukup    Mies  Nainen
työteht              
1           4       1
2          14       1
3          22       7
4          18       7
5           5       3
In [6]:
#seuraavassa lasken df_osa-dataframelle kaikki mahdolliset ristiintaulukoinnit
#alustan ExcelWriterin kirjoittamaan uuteen tiedostoon ristit.xlsx
writer = pd.ExcelWriter('ristit.xlsx', engine = 'xlsxwriter')

#pidän kirjaa rivinumerosta rivi-muuttujan avulla
rivi = 0

#for-silmukoilla käyn läpi kaikki muuttujaparit
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()