Datan valmistelu

Opittavia funktioita ja ominaisuuksia: head(), tail(), shape, columns, rename(), count(), unique(), replace(), cut(), mean(), sum(), notnull(), isnull(), sort_values(), drop()

Ohjelmakirjastot

Aluksi tuon (import) tarvittavat kirjastot. Data-analytiikassa tarvitaan aina pandas-kirjastoa. Pandas sisältää dataframe-tietorakenteen, jota tarvitaan taulukkomuotoiselle datalle. Vakiintuneen tavan mukaan käytän pandas-kirjastosta lyhennettä pd.

In [1]:
import pandas as pd

Datan avaaminen

Excel-muotoisen datan voin lukea pandas-kirjaston read_excel()-funktiolla. head()-funktio tulostaa datan viisi ensimmäistä riviä, tail()-funktio tulostaa viisi viimeistä riviä ja shape-ominaisuus antaa datan rivien ja sarakkeiden lukumäärän.

In [2]:
df = pd.read_excel('http://taanila.fi/data1.xlsx')
df.head()
Out[2]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja
0 1 1 38 1 1.0 22.0 3587 3 3.0 3 3 3 NaN NaN NaN NaN
1 2 1 29 2 2.0 10.0 2963 1 5.0 2 1 3 NaN NaN NaN NaN
2 3 1 30 1 1.0 7.0 1989 3 4.0 1 1 3 1.0 NaN NaN NaN
3 4 1 36 2 1.0 14.0 2144 3 3.0 3 3 3 1.0 NaN NaN NaN
4 5 1 24 1 2.0 4.0 2183 2 3.0 2 1 2 1.0 NaN NaN NaN
In [3]:
df.tail()
Out[3]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja
77 78 1 22 1 3.0 0.0 1598 4 4.0 4 3 4 NaN 1.0 1.0 NaN
78 79 1 33 1 1.0 2.0 1638 1 3.0 2 1 2 1.0 NaN NaN NaN
79 80 1 27 1 2.0 7.0 2612 3 4.0 3 3 3 1.0 NaN 1.0 NaN
80 81 1 35 2 2.0 16.0 2808 3 4.0 3 3 3 NaN NaN NaN NaN
81 82 2 35 2 3.0 15.0 2183 3 4.0 4 3 4 1.0 NaN NaN NaN
In [4]:
df.shape
Out[4]:
(82, 16)

Sarakkeet

Sarakkeiden (muuttujien) nimilistan saan tulostamalla columns-ominaisuuden. Voin vaihtaa muuttujien nimiä sijoittamalla muutetun nimilistan columns-ominaisuuden arvoksi. Muuttujien nimiä voin vaihtaa myös rename()-funktiolla.

Muuttujien arvojen lukumäärät selviävät count()-funktiolla.

In [5]:
df.columns
Out[5]:
Index(['nro', 'sukup', 'ikä', 'perhe', 'koulutus', 'palveluv', 'palkka',
       'johto', 'työtov', 'työymp', 'palkkat', 'työteht', 'työterv', 'lomaosa',
       'kuntosa', 'hieroja'],
      dtype='object')
In [6]:
#sijoitan muutetun nimilistan muuttujien nimiksi
df.columns = ['nro', 'sukupuoli', 'ikä', 'perhesuhde', 'koulutus', 'palveluv', 'palkka',
       'johto', 'työtov', 'työymp', 'palkkat', 'työteht', 'työterv', 'lomaosa',
       'kuntosa', 'hieroja']
df.columns
Out[6]:
Index(['nro', 'sukupuoli', 'ikä', 'perhesuhde', 'koulutus', 'palveluv',
       'palkka', 'johto', 'työtov', 'työymp', 'palkkat', 'työteht', 'työterv',
       'lomaosa', 'kuntosa', 'hieroja'],
      dtype='object')
In [7]:
#vaihdan muuttujien nimiä rename()-funktiolla
df.rename(columns = {'sukupuoli': 'sukup', 'perhesuhde': 'perhe'}, inplace = True)
df.head()
Out[7]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja
0 1 1 38 1 1.0 22.0 3587 3 3.0 3 3 3 NaN NaN NaN NaN
1 2 1 29 2 2.0 10.0 2963 1 5.0 2 1 3 NaN NaN NaN NaN
2 3 1 30 1 1.0 7.0 1989 3 4.0 1 1 3 1.0 NaN NaN NaN
3 4 1 36 2 1.0 14.0 2144 3 3.0 3 3 3 1.0 NaN NaN NaN
4 5 1 24 1 2.0 4.0 2183 2 3.0 2 1 2 1.0 NaN NaN NaN
In [8]:
df.count()
Out[8]:
nro         82
sukup       82
ikä         82
perhe       82
koulutus    81
palveluv    80
palkka      82
johto       82
työtov      81
työymp      82
palkkat     82
työteht     82
työterv     47
lomaosa     20
kuntosa      9
hieroja     22
dtype: int64
In [9]:
#puuttuvien havaintojen lukumäärät muuttujittain
df.isnull().sum()
Out[9]:
nro          0
sukup        0
ikä          0
perhe        0
koulutus     1
palveluv     2
palkka       0
johto        0
työtov       1
työymp       0
palkkat      0
työteht      0
työterv     35
lomaosa     62
kuntosa     73
hieroja     60
dtype: int64

Ainutkertaiset arvot

Muuttujan sisältämät ainutkertaiset arvot selviävät unique()-funktiolla. Seuraavassa käyn läpi kaikki muuttujat for-silmukalla.

In [10]:
for var in df:
    print(var, pd.unique(df[var]))
nro [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
 73 74 75 76 77 78 79 80 81 82]
sukup [1 2]
ikä [38 29 30 36 24 31 49 55 40 33 39 35 58 53 42 26 47 44 43 56 21 45 59 37
 28 50 32 51 22 34 27 41 25 61 20 52 46]
perhe [1 2]
koulutus [ 1.  2.  3.  4. nan]
palveluv [22. 10.  7. 14.  4. 16.  0. 23. 21. 15. 12.  2. 17. 20. 13. 27.  1.  3.
 nan 24.  5.  9.  6. 35. 28. 18. 36. 19.  8.]
palkka [3587 2963 1989 2144 2183 1910 2066 2768 2106 2651 2846 2808 3393 2691
 5225 2729 2925 2457 4874 3510 4446 1521 2223 1949 2340 6278 1559 2027
 2300 2534 1872 2261 2417 3119 2574 1715 5069 2495 3470 1598 1638 2612]
johto [3 1 2 4 5]
työtov [ 3.  5.  4.  2. nan]
työymp [3 2 1 5 4]
palkkat [3 1 2 4 5]
työteht [3 2 4 1 5]
työterv [nan  1.]
lomaosa [nan  1.]
kuntosa [nan  1.]
hieroja [nan  1.]

Uusien muuttujien laskeminen

replace()-funktiolla korvaan muuttujan arvoja uusilla arvoilla. cut()-funktiolla luokittelen määrällisen muuttujan arvot luokkiin. mean() ja sum() -funktioilla voin laskea keskiarvo- ja summamuuttujia. Lisäparametri axis=1 tarkoittaa laskemista vierekkäin samalla rivillä sijaitsevista luvuista.

In [11]:
#uusi muuttuja 'sukup_teksti', jossa sukupuolet tekstiarvoina
df['sukup_teksti'] = df['sukup'].replace({1 : 'Mies', 2 : 'Nainen'})
df.head(6)
Out[11]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti
0 1 1 38 1 1.0 22.0 3587 3 3.0 3 3 3 NaN NaN NaN NaN Mies
1 2 1 29 2 2.0 10.0 2963 1 5.0 2 1 3 NaN NaN NaN NaN Mies
2 3 1 30 1 1.0 7.0 1989 3 4.0 1 1 3 1.0 NaN NaN NaN Mies
3 4 1 36 2 1.0 14.0 2144 3 3.0 3 3 3 1.0 NaN NaN NaN Mies
4 5 1 24 1 2.0 4.0 2183 2 3.0 2 1 2 1.0 NaN NaN NaN Mies
5 6 2 31 2 2.0 14.0 1910 4 4.0 5 2 4 1.0 1.0 NaN NaN Nainen
In [12]:
#uusi muuttuja 'ikäluokka', jossa iät luokiteltuina ikäluokkiin
bins = [18, 28, 38, 48, 58, 68]
df['ikäluokka'] = pd.cut(df['ikä'], bins = bins)
df.head()
Out[12]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka
0 1 1 38 1 1.0 22.0 3587 3 3.0 3 3 3 NaN NaN NaN NaN Mies (28, 38]
1 2 1 29 2 2.0 10.0 2963 1 5.0 2 1 3 NaN NaN NaN NaN Mies (28, 38]
2 3 1 30 1 1.0 7.0 1989 3 4.0 1 1 3 1.0 NaN NaN NaN Mies (28, 38]
3 4 1 36 2 1.0 14.0 2144 3 3.0 3 3 3 1.0 NaN NaN NaN Mies (28, 38]
4 5 1 24 1 2.0 4.0 2183 2 3.0 2 1 2 1.0 NaN NaN NaN Mies (18, 28]
In [13]:
#lasken vastaajan "kokonaistyytyväisyyden" keskiarvona
df['tyytyväisyys'] = df[['johto','työtov','työymp','palkkat','työteht']].mean(axis=1)

df[['sukup','ikä','tyytyväisyys']].head()
Out[13]:
sukup ikä tyytyväisyys
0 1 38 3.0
1 1 29 2.4
2 1 30 2.4
3 1 36 3.0
4 1 24 2.0
In [14]:
#lasken käytettyjen etuisuuksien lukumäärän.
df['käyttö'] = df[['työterv', 'lomaosa', 'kuntosa', 'hieroja']].count(axis=1)
df.head(6)
Out[14]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka tyytyväisyys käyttö
0 1 1 38 1 1.0 22.0 3587 3 3.0 3 3 3 NaN NaN NaN NaN Mies (28, 38] 3.0 0
1 2 1 29 2 2.0 10.0 2963 1 5.0 2 1 3 NaN NaN NaN NaN Mies (28, 38] 2.4 0
2 3 1 30 1 1.0 7.0 1989 3 4.0 1 1 3 1.0 NaN NaN NaN Mies (28, 38] 2.4 1
3 4 1 36 2 1.0 14.0 2144 3 3.0 3 3 3 1.0 NaN NaN NaN Mies (28, 38] 3.0 1
4 5 1 24 1 2.0 4.0 2183 2 3.0 2 1 2 1.0 NaN NaN NaN Mies (18, 28] 2.0 1
5 6 2 31 2 2.0 14.0 1910 4 4.0 5 2 4 1.0 1.0 NaN NaN Nainen (28, 38] 3.8 2

Poimintaa ja suodatuksia

Voin muodostaa monimutkaisiakin poimintoja &- ja |-operaattoreita käyttäen.

notnull()- ja isnull()-funktioilla voin selvittää ei-tyhjät ja tyhjät.

sort_values()-funktio järjestää halutun muuttujan suhteen.

drop()-funktio pudottaa halutut muuttujat pois datasta.

In [15]:
#huomaa, että riviä 6 ei oteta mukaan
df[4:6]
Out[15]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka tyytyväisyys käyttö
4 5 1 24 1 2.0 4.0 2183 2 3.0 2 1 2 1.0 NaN NaN NaN Mies (18, 28] 2.0 1
5 6 2 31 2 2.0 14.0 1910 4 4.0 5 2 4 1.0 1.0 NaN NaN Nainen (28, 38] 3.8 2
In [16]:
#ne, joiden palkka on suurempi kuin 4000
df[df['palkka']>4000]
Out[16]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka tyytyväisyys käyttö
16 17 1 26 1 4.0 2.0 5225 5 5.0 5 4 5 NaN NaN 1.0 NaN Mies (18, 28] 4.8 1
21 22 1 47 2 3.0 17.0 4874 2 4.0 3 2 4 NaN 1.0 NaN NaN Mies (38, 48] 3.0 1
23 24 1 36 1 3.0 7.0 4446 3 4.0 3 4 5 NaN NaN NaN NaN Mies (28, 38] 3.8 0
32 33 1 59 2 3.0 15.0 6278 4 4.0 5 4 4 NaN 1.0 NaN NaN Mies (58, 68] 4.2 1
66 67 1 37 2 4.0 8.0 5069 3 4.0 3 2 2 1.0 1.0 NaN 1.0 Mies (28, 38] 2.8 3
In [17]:
#miehet, joiden tyytyväisyys palkaan on 1 (erittäin tyytymätön) tai 2 (tyytymätön)
df[(df['sukup']==2) & (df['palkkat']<3)]
Out[17]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka tyytyväisyys käyttö
5 6 2 31 2 2.0 14.0 1910 4 4.0 5 2 4 1.0 1.0 NaN NaN Nainen (28, 38] 3.8 2
17 18 2 38 2 3.0 17.0 2729 4 3.0 4 2 1 NaN NaN NaN NaN Nainen (28, 38] 2.8 0
27 28 2 56 1 1.0 15.0 2223 3 4.0 3 2 4 1.0 NaN NaN 1.0 Nainen (48, 58] 3.2 2
45 46 2 51 2 1.0 28.0 1989 3 3.0 2 2 3 1.0 NaN NaN 1.0 Nainen (48, 58] 2.6 2
46 47 2 22 1 3.0 21.0 1872 3 3.0 4 1 3 NaN NaN 1.0 NaN Nainen (18, 28] 2.8 1
62 63 2 51 2 2.0 10.0 1872 4 3.0 2 2 3 1.0 NaN NaN NaN Nainen (48, 58] 2.8 1
63 64 2 44 1 2.0 1.0 1715 4 4.0 3 2 3 1.0 NaN NaN 1.0 Nainen (38, 48] 3.2 2
64 65 2 35 2 2.0 17.0 2691 4 4.0 5 2 4 1.0 NaN NaN 1.0 Nainen (28, 38] 3.8 2
In [18]:
#ne, jotka ovat käyttäneet sekä työterveyshuoltoa että lomaosaketta
df[(df['työterv'].notnull()) & (df['lomaosa'].notnull())]
Out[18]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka tyytyväisyys käyttö
5 6 2 31 2 2.0 14.0 1910 4 4.0 5 2 4 1.0 1.0 NaN NaN Nainen (28, 38] 3.8 2
37 38 1 50 2 1.0 1.0 2027 5 5.0 4 1 4 1.0 1.0 NaN NaN Mies (48, 58] 3.8 2
65 66 2 37 2 1.0 16.0 2027 5 5.0 5 4 5 1.0 1.0 NaN NaN Nainen (28, 38] 4.8 2
66 67 1 37 2 4.0 8.0 5069 3 4.0 3 2 2 1.0 1.0 NaN 1.0 Mies (28, 38] 2.8 3
69 70 1 52 2 2.0 22.0 3119 3 4.0 3 2 2 1.0 1.0 NaN 1.0 Mies (48, 58] 2.8 3
In [19]:
#ne, jotka eivät ole käyttäneet mitään tarjotuista etuisuuksista
df[df['käyttö']==0]
Out[19]:
nro sukup ikä perhe koulutus palveluv palkka johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka tyytyväisyys käyttö
0 1 1 38 1 1.0 22.0 3587 3 3.0 3 3 3 NaN NaN NaN NaN Mies (28, 38] 3.0 0
1 2 1 29 2 2.0 10.0 2963 1 5.0 2 1 3 NaN NaN NaN NaN Mies (28, 38] 2.4 0
10 11 1 39 2 1.0 22.0 2651 3 5.0 3 1 3 NaN NaN NaN NaN Mies (38, 48] 3.0 0
13 14 1 58 2 3.0 21.0 3587 4 5.0 4 1 3 NaN NaN NaN NaN Mies (48, 58] 3.4 0
17 18 2 38 2 3.0 17.0 2729 4 3.0 4 2 1 NaN NaN NaN NaN Nainen (28, 38] 2.8 0
20 21 2 40 2 3.0 20.0 2691 2 4.0 5 3 4 NaN NaN NaN NaN Nainen (38, 48] 3.6 0
23 24 1 36 1 3.0 7.0 4446 3 4.0 3 4 5 NaN NaN NaN NaN Mies (28, 38] 3.8 0
38 39 1 30 1 2.0 10.0 2300 3 5.0 3 3 4 NaN NaN NaN NaN Mies (28, 38] 3.6 0
47 48 1 34 2 1.0 18.0 2183 4 5.0 4 1 3 NaN NaN NaN NaN Mies (28, 38] 3.4 0
58 59 1 20 1 2.0 1.0 2261 3 4.0 3 2 3 NaN NaN NaN NaN Mies (18, 28] 3.0 0
67 68 1 33 2 3.0 7.0 2417 2 4.0 3 1 4 NaN NaN NaN NaN Mies (28, 38] 2.8 0
68 69 1 28 2 2.0 1.0 3510 4 5.0 3 1 4 NaN NaN NaN NaN Mies (18, 28] 3.4 0
76 77 1 39 1 2.0 22.0 2183 4 5.0 3 1 2 NaN NaN NaN NaN Mies (38, 48] 3.0 0
80 81 1 35 2 2.0 16.0 2808 3 4.0 3 3 3 NaN NaN NaN NaN Mies (28, 38] 3.2 0
In [20]:
#kokonaistyytyväisyys niille, jotka ovat käyttäneet vähintään kolmea etuisuutta
df[['tyytyväisyys','käyttö']][df['käyttö']>=3]
Out[20]:
tyytyväisyys käyttö
25 2.4 3
30 3.6 3
34 3.2 3
66 2.8 3
69 2.8 3
In [21]:
#Palkat ja palkkatyytyväisyydet palkan mukaan järjestettynä
df[['palkka','palkkat']].sort_values(by='palkka').head()
Out[21]:
palkka palkkat
25 1521 1
35 1559 1
53 1559 1
75 1598 1
77 1598 3
In [22]:
#sama kuin edellä, mutta palkat laskevassa järjestyksessä
df[['palkka','palkkat']].sort_values(by='palkka', ascending=False).head()
Out[22]:
palkka palkkat
32 6278 4
16 5225 4
66 5069 2
21 4874 2
23 4446 4
In [23]:
#data ilman muuttujia nro, ikä, palveluv ja palkka
df.drop(['nro','ikä','palveluv','palkka'], axis=1).head()
Out[23]:
sukup perhe koulutus johto työtov työymp palkkat työteht työterv lomaosa kuntosa hieroja sukup_teksti ikäluokka tyytyväisyys käyttö
0 1 1 1.0 3 3.0 3 3 3 NaN NaN NaN NaN Mies (28, 38] 3.0 0
1 1 2 2.0 1 5.0 2 1 3 NaN NaN NaN NaN Mies (28, 38] 2.4 0
2 1 1 1.0 3 4.0 1 1 3 1.0 NaN NaN NaN Mies (28, 38] 2.4 1
3 1 2 1.0 3 3.0 3 3 3 1.0 NaN NaN NaN Mies (28, 38] 3.0 1
4 1 1 2.0 2 3.0 2 1 2 1.0 NaN NaN NaN Mies (18, 28] 2.0 1

Muutetun datan tallentaminen Excel-muotoon

Jos kansiossa on jo samanniminen tiedosto, niin menetät sen!

In [24]:
df.to_excel('valmisteltu.xlsx')