{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Päivitetty 2024-02-08 / Aki Taanila\n" ] } ], "source": [ "from datetime import datetime\n", "print(f'Päivitetty {datetime.now().date()} / Aki Taanila')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Lukumäärät ja prosentit value_counts-funktiolla\n", "\n", "Frekvenssitaulukot ja ristiintaulukoinnit voin laskea **crosstab**-funktiolla, mutta taitavalle käyttäjälle **value_counts**-funktio on kätevä.\n", "\n", "Seuraavassa esittelen value_counts niksejä." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 82 entries, 0 to 81\n", "Data columns (total 16 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 nro 82 non-null int64 \n", " 1 sukup 82 non-null int64 \n", " 2 ikä 82 non-null int64 \n", " 3 perhe 82 non-null int64 \n", " 4 koulutus 81 non-null float64\n", " 5 palveluv 80 non-null float64\n", " 6 palkka 82 non-null int64 \n", " 7 johto 82 non-null int64 \n", " 8 työtov 81 non-null float64\n", " 9 työymp 82 non-null int64 \n", " 10 palkkat 82 non-null int64 \n", " 11 työteht 82 non-null int64 \n", " 12 työterv 47 non-null float64\n", " 13 lomaosa 20 non-null float64\n", " 14 kuntosa 9 non-null float64\n", " 15 hieroja 22 non-null float64\n", "dtypes: float64(7), int64(9)\n", "memory usage: 10.4 KB\n" ] } ], "source": [ "import pandas as pd\n", "df = pd.read_excel('https://taanila.fi/data1.xlsx')\n", "df.info()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 82 entries, 0 to 81\n", "Data columns (total 17 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 nro 82 non-null int64 \n", " 1 sukup 82 non-null int64 \n", " 2 ikä 82 non-null int64 \n", " 3 perhe 82 non-null int64 \n", " 4 koulutus 81 non-null float64\n", " 5 palveluv 80 non-null float64\n", " 6 palkka 82 non-null int64 \n", " 7 johto 82 non-null int64 \n", " 8 työtov 81 non-null float64\n", " 9 työymp 82 non-null int64 \n", " 10 palkkat 82 non-null int64 \n", " 11 työteht 82 non-null int64 \n", " 12 työterv 47 non-null float64\n", " 13 lomaosa 20 non-null float64\n", " 14 kuntosa 9 non-null float64\n", " 15 hieroja 22 non-null float64\n", " 16 työteht_obj 82 non-null object \n", "dtypes: float64(7), int64(9), object(1)\n", "memory usage: 11.0+ KB\n" ] } ], "source": [ "# Lisään dataan yhden object-tyyppisen muuttujan\n", "df['työteht_obj'] = df['työteht'].replace({1:'Erittäin tyytymätön', 2:'Tyytymätön', 3:'Siltä väliltä',\n", " 4:'Tyytyväinen', 5:'Erittäin tyytyväinen'})\n", "\n", "# Nyt datassa on kokonaisluku (int64), liukuluku (float64) ja object-tyyppisiä muuttujia\n", "df.info()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Frekvenssien mukainen järjestys" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "työymp\n", "3 30\n", "4 23\n", "5 11\n", "2 9\n", "1 9\n", "Name: count, dtype: int64" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Oletuksena value_counts() järjestää frekvenssit suurimmasta pienimpään\n", "df['työymp'].value_counts()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
työymp
330
423
511
29
19
\n", "
" ], "text/plain": [ " f\n", "työymp \n", "3 30\n", "4 23\n", "5 11\n", "2 9\n", "1 9" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Tulos ei ole dataframe, mutta to_frame() muuntaa sen dataframeksi\n", "df['työymp'].value_counts().to_frame('f')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
työymp
29
19
511
423
330
\n", "
" ], "text/plain": [ " f\n", "työymp \n", "2 9\n", "1 9\n", "5 11\n", "4 23\n", "3 30" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ascending-parametrilla järjestän frekvenssit pienimmästä suurimpaan\n", "df['työymp'].value_counts(ascending=True).to_frame('f')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Muuttujan arvojen mukainen järjestys" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
työymp
19
29
330
423
511
\n", "
" ], "text/plain": [ " f\n", "työymp \n", "1 9\n", "2 9\n", "3 30\n", "4 23\n", "5 11" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# sort_index() järjestää muuttujan arvot pienimmästä suurimpaan (aakkos-/numerojärjestys)\n", "df['työymp'].value_counts().sort_index().to_frame('f')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
työymp
511
423
330
29
19
\n", "
" ], "text/plain": [ " f\n", "työymp \n", "5 11\n", "4 23\n", "3 30\n", "2 9\n", "1 9" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Myös päinvastainen järjestys on mahdollinen\n", "df['työymp'].value_counts().sort_index(ascending=False).to_frame('f')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
työteht_obj
Erittäin tyytymätön5
Erittäin tyytyväinen8
Siltä väliltä29
Tyytymätön15
Tyytyväinen25
\n", "
" ], "text/plain": [ " f\n", "työteht_obj \n", "Erittäin tyytymätön 5\n", "Erittäin tyytyväinen 8\n", "Siltä väliltä 29\n", "Tyytymätön 15\n", "Tyytyväinen 25" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# sort_index() laittaa object-tyypin arvot aakkosjärjestykseen\n", "# Tämä ei yleensä ole haluttu järjestys\n", "df['työteht_obj'].value_counts().sort_index().to_frame('f')" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
työteht_obj
Erittäin tyytymätön5
Tyytymätön15
Siltä väliltä29
Tyytyväinen25
Erittäin tyytyväinen8
\n", "
" ], "text/plain": [ " f\n", "työteht_obj \n", "Erittäin tyytymätön 5\n", "Tyytymätön 15\n", "Siltä väliltä 29\n", "Tyytyväinen 25\n", "Erittäin tyytyväinen 8" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Räätälöidyn järjestyksen saan listan ja reindex()-funktion avulla\n", "# Tärkeää: listassa pitää olla täsmälleen samat arvot kuin muuttujalla alun perin\n", "tyytyväisyydet = ['Erittäin tyytymätön', 'Tyytymätön', 'Siltä väliltä', 'Tyytyväinen', 'Erittäin tyytyväinen']\n", "df['työteht_obj'].value_counts().reindex(tyytyväisyydet).to_frame('f')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Puuttuvien arvojen näyttäminen" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
koulutus
1.027
2.030
3.022
4.02
NaN1
\n", "
" ], "text/plain": [ " f\n", "koulutus \n", "1.0 27\n", "2.0 30\n", "3.0 22\n", "4.0 2\n", "NaN 1" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Voin halutessani näyttää puuttuvat arvot\n", "df['koulutus'].value_counts(dropna=False).sort_index().to_frame('f')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Prosenttien näyttäminen" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 f%
Peruskoulu27,00000033,3
2. aste30,00000037,0
Korkeakoulu22,00000027,2
Ylempi korkeakoulu2,0000002,5
Yhteensä81,000000100,0
\n" ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Frekvenssit koulutus-muuttujalle\n", "df1 = df['koulutus'].value_counts().sort_index().to_frame('f')\n", "\n", "# Lisään prosenttisarakkeen\n", "# Prosentit saan parametrilla normalize = True\n", "df1['%'] = df['koulutus'].value_counts(normalize=True)*100\n", "\n", "# Lisään muuttujan arvoille tekstimuotoiset arvot\n", "koulutus = ['Peruskoulu', '2. aste', 'Korkeakoulu', 'Ylempi korkeakoulu']\n", "df1.index = koulutus\n", "\n", "# Lisään yhteensä-rivin\n", "df1.loc['Yhteensä'] = df1.sum()\n", "\n", "# Ulkoasun viimeistely\n", "df1.style.format({'koulutus':'{:.0f}', '%':'{:.1f}'}, decimal=',')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Luokiteltu jakauma" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
f
(1499.999, 2000.0]19
(2000.0, 2500.0]28
(2500.0, 3000.0]22
(3000.0, 8000.0]13
Yhteensä82
\n", "
" ], "text/plain": [ " f\n", "(1499.999, 2000.0] 19\n", "(2000.0, 2500.0] 28\n", "(2500.0, 3000.0] 22\n", "(3000.0, 8000.0] 13\n", "Yhteensä 82" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bins = [1500, 2000, 2500, 3000, 8000]\n", "\n", "df2 = df['palkka'].value_counts(bins=bins).sort_index().to_frame('f')\n", "\n", "df2.loc['Yhteensä'] = df2.sum()\n", "\n", "df2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ristiintaulukointi" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 MiesNainen
Peruskoulu225
2. aste237
Korkeakoulu157
Ylempi korkeakoulu2-
Yhteensä6219
\n" ], "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ristiintaulukoinnissa hyödynnän groupby()-funktiota\n", "# unstack siirtää sukupuolet sarakkeisiin\n", "df3= df.groupby('sukup')['koulutus'].value_counts().sort_index().unstack('sukup')\n", "\n", "# Koulutusten nimet aiemmin määritellystä listasta\n", "df3.index = koulutus\n", "\n", "df3.loc['Yhteensä'] = df3.sum()\n", "\n", "# Sarakeotsikot\n", "df3.columns=['Mies', 'Nainen']\n", "\n", "# Ulkoasu ilman desimaaleja, puuttuvan arvon tilalla viiva\n", "df3.style.format(precision=0, na_rep='-')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Samalla asteikolla mitattujen frekvenssit yhteen taulukkoon" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 johto, n = 82työtov, n = 81työymp, n = 82palkkat, n = 82työteht, n = 82
Erittäin tyytymätön8,5 %-11,0 %40,2 %6,1 %
Tyytymätön19,5 %3,7 %11,0 %23,2 %18,3 %
Siltä väliltä36,6 %19,8 %36,6 %23,2 %35,4 %
Tyytyväinen28,0 %43,2 %28,0 %12,2 %30,5 %
Erittäin tyytyväinen7,3 %33,3 %13,4 %1,2 %9,8 %
Yhteensä100,0 %100,0 %100,0 %100,0 %100,0 %
\n" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ensimmäisen muuttujan frekvenssiprosentit\n", "df4 = df['johto'].value_counts(normalize=True).sort_index().to_frame('johto')\n", "\n", "# Lisään muiden muuttujien frekvenssiprosentit\n", "df4['työtov'] = df['työtov'].value_counts(sort=False, normalize=True)\n", "df4['työymp'] = df['työymp'].value_counts(sort=False, normalize=True)\n", "df4['palkkat'] = df['palkkat'].value_counts(sort=False, normalize=True)\n", "df4['työteht'] = df['työteht'].value_counts(sort=False, normalize=True)\n", "\n", "# Asteikon arvot tekstimuodossa aiemmin määritellystä tyytyväisyydet-listasta\n", "df4.index = tyytyväisyydet\n", "\n", "df4.loc['Yhteensä'] = df4.sum()\n", "\n", "# n-arvot sarakeotsikoihin\n", "for var in df4.columns:\n", " df4 = df4.rename(columns={var:f'{var}, n = {df[var].count()}'})\n", "\n", "# Ulkoasun viimeistely\n", "(df4*100).style.format('{:.1f} %', na_rep='-', decimal=',')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lisätietoa\n", "\n", "* https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.value_counts.html\n", "\n", "Data-analytiikka Pythonilla https://tilastoapu.wordpress.com/python/\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.5" } }, "nbformat": 4, "nbformat_minor": 4 }