from datetime import datetime
print(f'Päivitetty {datetime.now().strftime("%d.%m.%Y")} / Tatu Erkinjuntti')
Päivitetty 20.10.2024 / Tatu Erkinjuntti
Oppillaan kommentti: Itse en pidä yhdysvaltaistyylisestä päiväyksen formatoinnista kun ohjelma suoritetaan/luetaan tilanteessa jossa lukija on tottunut "perinteiseen" formatointiin => "day"."month"."year", kuten Suomessa yleisesti käytössä. Tästä syystä datetime formatointi on päivitetty tehtävässäni.
Tehtävä 1.¶
Kuvaus¶
Tehtävässä 1 on tarkoituksena soveltaa kuvailevan ja selittävän analytiikan menetelmiä valitsemiisi datoihin. Voit käyttää alempana mainittuja data-paketin datoja tai omaan työhön tai kiinnnostuksen kohteisiin liittyviä datoja. Käytä tehtävässä vähintään kahta eri datasettiä ja huolehdi että saat mukaan sekä kategorisia että määrällisiä muuttujia.
Tehtävän kriteerit¶
Täysiin pisteisiin (5) pääset soveltamalla kaikkia esimerkkimuistioissa esitettyjä menetelmiä:
- frekvenssitaulukot,
- luokitellut jakaumat,
- tilastolliset tunnusluvut, ristiintaulukoinnit,
- tunnuslukujen vertailut ja korrelaatiot
- tulosten visualisointeja.
Tehtävän alustus¶
Haetaan tarvittavat kirjastot ja määritellään käytetyt data-aineistot. Itse teen tämän aina kerralla ohjelman alussa, näin yhdellä silmäyksellä näkee ohjelman riippuvaisuudet. Jos käytössä olisi pysyviä muuttujia, tulisi ne myös alustaa samalla.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import pearsonr
from scipy.stats import ttest_ind
# Kaavioiden prosenttiakselin muotoiluun
from matplotlib.ticker import PercentFormatter
ticks = PercentFormatter(xmax=100, decimals=0, symbol=' %')
sns.set_style('dark')
data_titanic = '../Data/titanic_new.xlsx'
data_kunnat = '../Data/kunnat.xlsx'
data_sales = "../Data/sales_data_sample.csv"
Titanic¶
Aloitan tehtävän tutkimalla 1912 uponeen matkustajalaivan matkustajia käsitelevää data-pakettia.
## Luetaan excel-tiedosto
df_titanic = pd.read_excel(data_titanic)
## Tarkastellaan mitä datapaketti sisältää, samalla nähdään rivien ja sarakkeiden lukumäärä.
df_titanic
| Unnamed: 0 | pclass | survived | name | sex | age | sibsp | parch | ticket | fare | cabin | embarked | boat | body | home.dest | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 1 | Haghish, E. F. | male | 30.0000 | 0 | 0 | 24058 | 26.5500 | A1 Special | S | 1 | NaN | Odense, Denmark |
| 1 | 1 | 1 | 1 | Allen, Miss. Elisabeth Walton | female | 29.0000 | 0 | 0 | 24160 | 211.3375 | B5 | S | 2 | NaN | St Louis, MO |
| 2 | 2 | 1 | 1 | Allison, Master. Hudson Trevor | male | 0.9167 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | 11 | NaN | Montreal, PQ / Chesterville, ON |
| 3 | 3 | 1 | 0 | Allison, Miss. Helen Loraine | female | 2.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | NaN | Montreal, PQ / Chesterville, ON |
| 4 | 4 | 1 | 0 | Allison, Mr. Hudson Joshua Creighton | male | 30.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | 135.0 | Montreal, PQ / Chesterville, ON |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1305 | 1305 | 3 | 0 | Zabour, Miss. Hileni | female | 14.5000 | 1 | 0 | 2665 | 14.4542 | NaN | C | NaN | 328.0 | NaN |
| 1306 | 1306 | 3 | 0 | Zabour, Miss. Thamine | female | NaN | 1 | 0 | 2665 | 14.4542 | NaN | C | NaN | NaN | NaN |
| 1307 | 1307 | 3 | 0 | Zakarian, Mr. Mapriededer | male | 26.5000 | 0 | 0 | 2656 | 7.2250 | NaN | C | NaN | 304.0 | NaN |
| 1308 | 1308 | 3 | 0 | Zakarian, Mr. Ortin | male | 27.0000 | 0 | 0 | 2670 | 7.2250 | NaN | C | NaN | NaN | NaN |
| 1309 | 1309 | 3 | 0 | Zimmerman, Mr. Leo | male | 29.0000 | 0 | 0 | 315082 | 7.8750 | NaN | S | NaN | NaN | NaN |
1310 rows × 15 columns
## Tarkastellaan seuraavaksi käytössä olevia tietotyyppejä.
df_titanic.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1310 entries, 0 to 1309 Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Unnamed: 0 1310 non-null int64 1 pclass 1310 non-null int64 2 survived 1310 non-null int64 3 name 1310 non-null object 4 sex 1310 non-null object 5 age 1047 non-null float64 6 sibsp 1310 non-null int64 7 parch 1310 non-null int64 8 ticket 1310 non-null object 9 fare 1309 non-null float64 10 cabin 296 non-null object 11 embarked 1308 non-null object 12 boat 487 non-null object 13 body 121 non-null float64 14 home.dest 746 non-null object dtypes: float64(3), int64(5), object(7) memory usage: 153.6+ KB
Muuttujatyypit ovat olettavan laisia, int64 = kokonaisluku, float64 = liukuluku, object = tekstimuuttuja ('String'). Samalla huomaamme että aineistosta löytyy eroavaisuuksia merkintöjen osalta. Oletuksella aineosto kattaa 1310 matkustajan tiedot mutta kaikkia sarakkeita ei syystä tai toisesta ole täytetty. Esim. Sukupuolen osalta löytyy merkintä kaikkien osalta mutta iän osalta merkintöjä on vain 1047 matkustajan osalta.
Jatkketaan tutkimalla yleisiä tilastollisia tunnuslukuja suhteessa matkustajamäärää, näitä on esim. sukupuoli ja ikä jakauma
# Otetaan yleinen kuva data-aineistosta
df_titanic.describe()
| Unnamed: 0 | pclass | survived | age | sibsp | parch | fare | body | |
|---|---|---|---|---|---|---|---|---|
| count | 1310.000000 | 1310.000000 | 1310.000000 | 1047.000000 | 1310.000000 | 1310.000000 | 1309.000000 | 121.000000 |
| mean | 654.500000 | 2.293893 | 0.382443 | 29.881248 | 0.498473 | 0.384733 | 33.290326 | 160.809917 |
| std | 378.308736 | 0.838280 | 0.486169 | 14.406609 | 1.041352 | 0.865295 | 51.739215 | 97.696922 |
| min | 0.000000 | 1.000000 | 0.000000 | 0.166700 | 0.000000 | 0.000000 | 0.000000 | 1.000000 |
| 25% | 327.250000 | 2.000000 | 0.000000 | 21.000000 | 0.000000 | 0.000000 | 7.895800 | 72.000000 |
| 50% | 654.500000 | 3.000000 | 0.000000 | 28.000000 | 0.000000 | 0.000000 | 14.454200 | 155.000000 |
| 75% | 981.750000 | 3.000000 | 1.000000 | 39.000000 | 1.000000 | 0.000000 | 31.275000 | 256.000000 |
| max | 1309.000000 | 3.000000 | 1.000000 | 80.000000 | 8.000000 | 9.000000 | 512.329200 | 328.000000 |
Matkustajien iästä saadaan jo hyvin paljon tietoa tässä vaiheessa. Iän keskiarvo on hieman alle 30 vuotta, vanhin matkustaja on iältään 80 ja nuorin on vauvaikäinen. Kuten aikaisemmin tuli jo ilmi, niin otanta ei koske kaikkia, joten täyttä varmuutta tarkasta ikäjakaumasta ei ikävä kyllä saada.
# Aloitetaan tutkimalla sukupuolijakaumaa, muutetaan ensiksi taulukosta muutaman sarakkeen nimi kuvaavammaksi Suomenkielellä-
df_titanic = df_titanic.rename(columns={'sex':'sukupuoli','pclass':'matkustajaluokka'})
df_titanic.head() # Tarkastetaan vain ensimmäiset rivit
| Unnamed: 0 | matkustajaluokka | survived | name | sukupuoli | age | sibsp | parch | ticket | fare | cabin | embarked | boat | body | home.dest | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 1 | Haghish, E. F. | male | 30.0000 | 0 | 0 | 24058 | 26.5500 | A1 Special | S | 1 | NaN | Odense, Denmark |
| 1 | 1 | 1 | 1 | Allen, Miss. Elisabeth Walton | female | 29.0000 | 0 | 0 | 24160 | 211.3375 | B5 | S | 2 | NaN | St Louis, MO |
| 2 | 2 | 1 | 1 | Allison, Master. Hudson Trevor | male | 0.9167 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | 11 | NaN | Montreal, PQ / Chesterville, ON |
| 3 | 3 | 1 | 0 | Allison, Miss. Helen Loraine | female | 2.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | NaN | Montreal, PQ / Chesterville, ON |
| 4 | 4 | 1 | 0 | Allison, Mr. Hudson Joshua Creighton | male | 30.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | 135.0 | Montreal, PQ / Chesterville, ON |
# Tarkastetaan ensiksi sukupuolijakauma.
# Frekvenssi-sarakkeen otsikkona käytetään yleisesti f-kirjainta.
df_titanic_gender = pd.crosstab(df_titanic['sukupuoli'], columns='f')
# Poistetaan 'Col_0' otsikko ensimmäisestä sarakkeesta.
df_titanic_gender.columns.name=''
# Suomennetaan sukupuolet
gender = ['Nainen', 'Mies']
df_titanic_gender.index = gender
# Lisätään mukaan prosentti-sarake jotta määrällinen ero on selkeämpi.
n = df_titanic_gender['f'].sum()
df_titanic_gender['%'] = df_titanic_gender['f']/n*100
# Lisätään vielä rivi jossa näytetään yhteenlaskettu määrä.
df_titanic_gender.loc['Yhteensä'] = df_titanic_gender.loc['Nainen':'Mies'].sum()
# Hieman siistitään ulkoasua, f-sareke ei tarvitse erikseen desimaalia ja % sarake voisi olla kahden desimaalin tarkkuudella..
df_titanic_gender.style.format({'f':'{:.0f}', '%':'{:.1f} %'})
| f | % | |
|---|---|---|
| Nainen | 466 | 35.6 % |
| Mies | 844 | 64.4 % |
| Yhteensä | 1310 | 100.0 % |
Jakauma sukupuolten välillä nyt selkeä mutta tehdään tästä vielä helppolukuinen pylväs diagrammi.
# luodaan pylväsdiagrammin sukupuolten prosenttisuhteista.
df_titanic_gender.drop('Yhteensä')['%'].plot(kind='barh', title='Titanic-laivan sukupuolijakauma', xlabel=(f'Havaintojen lukumäärä (n = {n}) = 100%'), ylabel='')
# määritetään myös x-akselilta lähtevä taustaviivoitus.
plt.grid(axis='x')
# määritellään vielä x-akselin lukuihin prosentit.
plt.gca().xaxis.set_major_formatter(ticks)
Sukupuolijakauman osalta voidaan tehdä yleinen tulkinta, miehet edustavat 2/3 osaa matkustajista. Onko tämä jakauma tyyppillinen tuohon aikakauteen, on kysymys mihin on vaikea antaa vastausta tämän perusteella.
Tutkitaan seuraavaksi matkustajien ikä jakaumaa.
#Suomennetaan taas yksi sarake taulukosta
df_titanic = df_titanic.rename(columns={'age':'ikä'})
# Jaetaan itä johdonmukaisiin ryhmiin, näin on lapsi, nuori, aikuinen ja vanhus. Viitettä tähän ikäjakaukumaan haettiin Wikipediasta
# lapsi = 0-13 vuotta
# nuori = 13-22 vuotta
# aikuinen = 22 - 60 vuotta
# vanhus = 60 - 80 vuotta -- Muistetaan että tiedämme jo että vanhin matkustaja on 80 vuotias.
age_groups = [0,13,22,60,80,]
# Lisätään taulukkoon ikäluokka-sarake
df_titanic['ikäluokka'] = pd.cut(df_titanic['ikä'], bins=age_groups, right=False)
#Tarkastetaan muutokset
df_titanic.head()
| Unnamed: 0 | matkustajaluokka | survived | name | sukupuoli | ikä | sibsp | parch | ticket | fare | cabin | embarked | boat | body | home.dest | ikäluokka | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 1 | Haghish, E. F. | male | 30.0000 | 0 | 0 | 24058 | 26.5500 | A1 Special | S | 1 | NaN | Odense, Denmark | [22, 60) |
| 1 | 1 | 1 | 1 | Allen, Miss. Elisabeth Walton | female | 29.0000 | 0 | 0 | 24160 | 211.3375 | B5 | S | 2 | NaN | St Louis, MO | [22, 60) |
| 2 | 2 | 1 | 1 | Allison, Master. Hudson Trevor | male | 0.9167 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | 11 | NaN | Montreal, PQ / Chesterville, ON | [0, 13) |
| 3 | 3 | 1 | 0 | Allison, Miss. Helen Loraine | female | 2.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | NaN | Montreal, PQ / Chesterville, ON | [0, 13) |
| 4 | 4 | 1 | 0 | Allison, Mr. Hudson Joshua Creighton | male | 30.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | 135.0 | Montreal, PQ / Chesterville, ON | [22, 60) |
Tarkastellaan vielä vielä ikäluokkien frekvenssit.
# Tarkastetaan ensiksi sukupuolijakauma.
# Frekvenssi-sarakkeen otsikkona käytetään yleisesti f-kirjainta.
df_titanic_age = pd.crosstab(df_titanic['ikäluokka'], columns='f')
# Poistetaan 'Col_0' otsikko ensimmäisestä sarakkeesta.
df_titanic_age.columns.name=''
# Suomennetaan sukupuolet
df_titanic_age.index = ['Lapsi', 'Nuori', 'Aikuinen', 'Vanhus']
# Lisätään mukaan prosentti-sarake jotta määrällinen ero on selkeämpi.
n = df_titanic_age['f'].sum()
df_titanic_age['%'] = df_titanic_age['f']/n*100
# Lisätään vielä rivi jossa näytetään yhteenlaskettu määrä.
df_titanic_age.loc['Yhteensä'] = df_titanic_age.loc['Lapsi':'Vanhus'].sum()
# Hieman siistitään ulkoasua, f-sareke ei tarvitse erikseen desimaalia ja % sarake voisi olla kahden desimaalin tarkkuudella..
df_titanic_age.style.format({'f':'{:.0f}', '%':'{:.1f} %'})
| f | % | |
|---|---|---|
| Lapsi | 94 | 9.0 % |
| Nuori | 196 | 18.7 % |
| Aikuinen | 717 | 68.5 % |
| Vanhus | 39 | 3.7 % |
| Yhteensä | 1046 | 100.0 % |
Aikuiset ovat listalla selkeästi yliedustettuja.
Tehdään ikäluokan jako 10 vuoden välein ja tehdään histogrammi, jotta saadaan paremmin kuvaa otannan ikäsuhteista.
Tarkastellaan näitä prosentteina, jotta kokonaisuuden hahmottaminen on helpompaa.
# Tyhjennetään lista ja populoidaan se uudestaan tarkemilla raja-arvoilla.
age_groups.clear()
for i in range(0, 90, 10):
age_groups.append(i)
#Lisätään taulukkoon ikäluokka-sarake
df_titanic['ikäluokka'] = pd.cut(df_titanic['ikä'], bins=age_groups, right=False)
#Tarkastetaan muutokset
df_titanic.head()
| Unnamed: 0 | matkustajaluokka | survived | name | sukupuoli | ikä | sibsp | parch | ticket | fare | cabin | embarked | boat | body | home.dest | ikäluokka | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 1 | Haghish, E. F. | male | 30.0000 | 0 | 0 | 24058 | 26.5500 | A1 Special | S | 1 | NaN | Odense, Denmark | [30, 40) |
| 1 | 1 | 1 | 1 | Allen, Miss. Elisabeth Walton | female | 29.0000 | 0 | 0 | 24160 | 211.3375 | B5 | S | 2 | NaN | St Louis, MO | [20, 30) |
| 2 | 2 | 1 | 1 | Allison, Master. Hudson Trevor | male | 0.9167 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | 11 | NaN | Montreal, PQ / Chesterville, ON | [0, 10) |
| 3 | 3 | 1 | 0 | Allison, Miss. Helen Loraine | female | 2.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | NaN | Montreal, PQ / Chesterville, ON | [0, 10) |
| 4 | 4 | 1 | 0 | Allison, Mr. Hudson Joshua Creighton | male | 30.0000 | 1 | 2 | 113781 | 151.5500 | C22 C26 | S | NaN | 135.0 | Montreal, PQ / Chesterville, ON | [30, 40) |
# Määritellään histogrammi käsittelemään prosentteja
sns.histplot(df_titanic['ikä'], bins=age_groups, stat='percent')
# Lisätään Y-akselille prosenttimerkit
plt.gca().yaxis.set_major_formatter(ticks)
# Nimetään X-akseli
plt.xlabel('Ikäluokka')
plt.ylabel(f'%, n = {n}')
Text(0, 0.5, '%, n = 1046')
Nyt saadaan selkeämpää kuvaa ikäjakaumasta, voidaan todeta että 20 - 40 vuotiaat aikuiset edustivat isoa osaa matkustajista.
Tehdään vielä ristiintaulukointi jotta saadaan selville iän ja sukupuolen suhde matkustajissa. Koska tiedämme että tämän osalta on merkinnöissä vajaavaisuuksia, voitaisiin samalla katsoa kummalta sukupuolelta enemmän merkintöjä iän osalta.
# Tarkastetaan ensiksi puuttuvien merkintöjen suhde sukupuolten välillä.
# Tehdään ristiintaulukointi, mutta tutkitaan sarakkeen puttuvia arvoja.
df_titanic_age_gender_nan = pd.crosstab(df_titanic['ikäluokka'].isna().values, df_titanic['sukupuoli'])
# Lisätään mukaan kuvaukset sarakkeille ja nimille.
df_titanic_age_gender_nan.columns = gender
df_titanic_age_gender_nan.columns.name = 'Sukupuoli'
df_titanic_age_gender_nan.index = ['Kyllä', 'Ei'] # HUOM! isna().values palauttaa Booleanin (True/False) siitä onko rivi/sarake tyhjä vai ei. Tästä syystä nimeämiset menee päittäin, esim. False = merkintä löytyy (rivi ei ole tyhjä) ja tämä merkitään muotoon 'Löytyy' / 'Kyllä' jne.
df_titanic_age_gender_nan.index.name='Ikä merkintä löytyy'
# Lisätään vielä rivi jossa näytetään yhteenlaskettu määrä.
df_titanic_age_gender_nan
| Sukupuoli | Nainen | Mies |
|---|---|---|
| Ikä merkintä löytyy | ||
| Kyllä | 388 | 658 |
| Ei | 78 | 186 |
Huomataan että miesten osalta iän merkintä puuttuu huomattavasti useammin kuin naisilla.
# Tehdään ristiinlasku ikäluokan ja sukupuolen perusteella.
df_titanic_age_gender = pd.crosstab(df_titanic['ikäluokka'], df_titanic['sukupuoli'])
df_titanic_age_gender.columns = gender
df_titanic_age_gender
| Nainen | Mies | |
|---|---|---|
| ikäluokka | ||
| [0, 10) | 39 | 43 |
| [10, 20) | 64 | 79 |
| [20, 30) | 115 | 229 |
| [30, 40) | 86 | 147 |
| [40, 50) | 46 | 89 |
| [50, 60) | 27 | 43 |
| [60, 70) | 10 | 22 |
| [70, 80) | 1 | 6 |
g = sns.displot(data=df_titanic, x='ikä', col='sukupuoli', kind='hist', bins=age_groups, height=3, aspect=1,stat='percent')
g.set_ylabels('')
plt.gca().yaxis.set_major_formatter(ticks)
for ax, title in zip(g.axes.flatten(), ['Mies', 'Nainen']):
ax.set_title(title)
Koska tiedämme että data-aineistosta puuttuu merkintöjä iän osalta, voimme suhtauta tähän suuntaa-antavasti. 20-40 vuotiaat miehet edustivat tämän otannan puolesta isointa osaa matkustajista. Voi yleisesti todeta että ikäjakauma on sukupuolten välisiin matkustajamääriin suhteutettuna saman tyyppinen.
Kunnat¶
Jatketaan tehtävää tutkimalla Suomen kuntia käsittelevää data-aineistoa.
# Aloitetaan lukemalla Excel-tiedosto
df_municipality = pd.read_excel(data_kunnat)
# Tarkastellaan hieman mitä data aineisto sisältää
df_municipality
| Unnamed: 0 | Taajama-aste, %, 2020 | Väkiluku, 2021 | Väkiluvun muutos edellisestä vuodesta, %, 2021 | Alle 15-vuotiaiden osuus väestöstä, %, 2021 | 15-64 -vuotiaiden osuus väestöstä, %, 2021 | Yli 64-vuotiaiden osuus väestöstä, %, 2021 | Ruotsinkielisten osuus väestöstä, %, 2021 | Ulkomaan kansalaisten osuus väestöstä, %, 2021 | Syntyneiden enemmyys, henkilöä, 2021 | ... | Alueella olevien työpaikkojen lukumäärä, 2020 | Alkutuotannon työpaikkojen osuus, %, 2020 | Jalostuksen työpaikkojen osuus, %, 2020 | Palvelujen työpaikkojen osuus, %, 2020 | Työpaikkaomavaraisuus, 2020 | Vuosikate, euroa/asukas, 2020 | Lainakanta, euroa/asukas, 2020 | Konsernin lainakanta, euroa/asukas, 2020 | Opetus- ja kulttuuritoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | Sosiaali- ja terveystoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Akaa | 87.9 | 16467 | 0.5 | 16.3 | 58.9 | 24.8 | 0.2 | 1.9 | -15 | ... | 4432 | 3.1 | 33.8 | 61.4 | 67.4 | 1066.9 | 3199.6 | 4623.2 | 1801.7 | 3252.7 |
| 1 | Alajärvi | 61.6 | 9311 | -1.1 | 16.9 | 53.5 | 29.5 | 0.1 | 2.7 | -45 | ... | 3302 | 11.5 | 27.2 | 59.4 | 100.0 | 599.7 | 2942.5 | 5437.3 | 2322.5 | 4142.8 |
| 2 | Alavieska | 51.6 | 2491 | -1.0 | 19.4 | 54.9 | 25.7 | 0.2 | 0.6 | -6 | ... | 704 | 22.4 | 21.3 | 54.4 | 72.1 | 783.1 | 3973.0 | 4469.2 | 2028.2 | 4153.8 |
| 3 | Alavus | 60.8 | 11197 | -1.2 | 16.4 | 53.9 | 29.7 | 0.1 | 1.3 | -70 | ... | 4056 | 9.0 | 21.0 | 68.5 | 96.4 | 456.8 | 4029.7 | 7135.7 | 1990.8 | 4354.0 |
| 4 | Asikkala | 65.0 | 8033 | -0.3 | 13.3 | 52.4 | 34.3 | 0.2 | 1.9 | -72 | ... | 2282 | 8.6 | 30.7 | 57.9 | 79.5 | 1072.8 | 241.3 | 1623.5 | 1752.7 | 3559.3 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 304 | Ylivieska | 85.9 | 15357 | 0.3 | 20.8 | 58.2 | 21.0 | 0.3 | 1.1 | 34 | ... | 6587 | 2.4 | 21.1 | 75.5 | 106.5 | 734.0 | 7927.1 | 8720.0 | 2584.2 | 3672.5 |
| 305 | Ylöjärvi | 88.7 | 33533 | 0.5 | 20.5 | 60.5 | 19.0 | 0.3 | 1.4 | 130 | ... | 9714 | 2.3 | 28.8 | 67.1 | 66.8 | 526.0 | 2463.4 | 3498.5 | 2266.7 | 2951.1 |
| 306 | Ypäjä | 41.1 | 2282 | -1.4 | 11.6 | 58.5 | 29.9 | 0.7 | 1.1 | -14 | ... | 595 | 19.8 | 15.6 | 60.5 | 61.8 | 855.2 | 1506.1 | 2228.2 | 1569.6 | 3297.8 |
| 307 | Ähtäri | 61.9 | 5484 | -0.7 | 13.4 | 52.4 | 34.2 | 0.1 | 1.2 | -52 | ... | 2029 | 10.7 | 25.2 | 62.5 | 101.1 | 586.6 | 3621.9 | 9556.5 | 1544.0 | 4759.7 |
| 308 | Äänekoski | 76.8 | 18318 | -1.4 | 14.9 | 56.5 | 28.6 | 0.1 | 1.4 | -109 | ... | 6683 | 2.5 | 41.7 | 54.5 | 104.6 | 596.2 | 3990.7 | 10195.5 | 2027.8 | 3996.9 |
309 rows × 33 columns
# Tarkastellaan vielä hieman tunnuslukuja
df_municipality.describe()
| Taajama-aste, %, 2020 | Väkiluku, 2021 | Väkiluvun muutos edellisestä vuodesta, %, 2021 | Alle 15-vuotiaiden osuus väestöstä, %, 2021 | 15-64 -vuotiaiden osuus väestöstä, %, 2021 | Yli 64-vuotiaiden osuus väestöstä, %, 2021 | Ruotsinkielisten osuus väestöstä, %, 2021 | Ulkomaan kansalaisten osuus väestöstä, %, 2021 | Syntyneiden enemmyys, henkilöä, 2021 | Kuntien välinen muuttovoitto/-tappio, henkilöä, 2021 | ... | Alueella olevien työpaikkojen lukumäärä, 2020 | Alkutuotannon työpaikkojen osuus, %, 2020 | Jalostuksen työpaikkojen osuus, %, 2020 | Palvelujen työpaikkojen osuus, %, 2020 | Työpaikkaomavaraisuus, 2020 | Vuosikate, euroa/asukas, 2020 | Lainakanta, euroa/asukas, 2020 | Konsernin lainakanta, euroa/asukas, 2020 | Opetus- ja kulttuuritoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | Sosiaali- ja terveystoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | ... | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 | 309.000000 |
| mean | 61.875405 | 17955.472492 | -0.465372 | 14.753074 | 55.580259 | 29.664401 | 9.430421 | 3.106796 | -26.100324 | 0.000000 | ... | 7393.737864 | 10.440453 | 23.763754 | 63.682201 | 85.753074 | 677.923301 | 3341.946278 | 5602.757282 | 2005.773463 | 4065.811327 |
| std | 22.066455 | 50084.667410 | 1.182886 | 3.889350 | 4.357919 | 7.060984 | 24.392197 | 3.158197 | 172.848104 | 305.371522 | ... | 27126.461941 | 7.539232 | 9.990754 | 10.330891 | 19.797897 | 380.002042 | 1818.144829 | 2923.164014 | 338.187718 | 878.299303 |
| min | 0.000000 | 105.000000 | -4.800000 | 4.000000 | 46.500000 | 10.800000 | 0.000000 | 0.200000 | -587.000000 | -4210.000000 | ... | 22.000000 | 0.100000 | 2.300000 | 22.300000 | 34.600000 | -583.300000 | 0.000000 | 0.000000 | 366.300000 | 1221.900000 |
| 25% | 47.300000 | 2673.000000 | -1.200000 | 12.100000 | 52.300000 | 25.000000 | 0.100000 | 1.400000 | -65.000000 | -30.000000 | ... | 807.000000 | 3.800000 | 17.200000 | 57.300000 | 71.500000 | 502.100000 | 2037.900000 | 3587.400000 | 1783.300000 | 3463.200000 |
| 50% | 60.800000 | 5967.000000 | -0.600000 | 14.400000 | 55.500000 | 29.300000 | 0.300000 | 2.100000 | -31.000000 | -5.000000 | ... | 1849.000000 | 9.500000 | 22.900000 | 63.900000 | 86.800000 | 664.900000 | 3287.500000 | 5400.200000 | 1964.200000 | 4010.600000 |
| 75% | 77.400000 | 14643.000000 | 0.200000 | 16.900000 | 58.300000 | 35.100000 | 0.800000 | 3.500000 | -7.000000 | 20.000000 | ... | 4648.000000 | 15.500000 | 28.800000 | 70.200000 | 99.100000 | 838.000000 | 4287.900000 | 7173.600000 | 2211.300000 | 4673.800000 |
| max | 100.000000 | 658457.000000 | 4.000000 | 30.800000 | 68.100000 | 44.600000 | 92.400000 | 25.700000 | 1594.000000 | 1816.000000 | ... | 398042.000000 | 33.500000 | 68.100000 | 92.600000 | 160.900000 | 4897.100000 | 10897.800000 | 18154.800000 | 3088.500000 | 6778.700000 |
8 rows × 32 columns
Tarkastellaan ensiksi oleellisimmat asia. Listaan vaikka top 10 kunta väkiluvun perusteella.
# Napataan 10 suurinta kuntaa väkiluvun perusteella ja tallennetaan se uuteen data-frameen.
df_municipality.nlargest(10,'Väkiluku, 2021')
| Unnamed: 0 | Taajama-aste, %, 2020 | Väkiluku, 2021 | Väkiluvun muutos edellisestä vuodesta, %, 2021 | Alle 15-vuotiaiden osuus väestöstä, %, 2021 | 15-64 -vuotiaiden osuus väestöstä, %, 2021 | Yli 64-vuotiaiden osuus väestöstä, %, 2021 | Ruotsinkielisten osuus väestöstä, %, 2021 | Ulkomaan kansalaisten osuus väestöstä, %, 2021 | Syntyneiden enemmyys, henkilöä, 2021 | ... | Alueella olevien työpaikkojen lukumäärä, 2020 | Alkutuotannon työpaikkojen osuus, %, 2020 | Jalostuksen työpaikkojen osuus, %, 2020 | Palvelujen työpaikkojen osuus, %, 2020 | Työpaikkaomavaraisuus, 2020 | Vuosikate, euroa/asukas, 2020 | Lainakanta, euroa/asukas, 2020 | Konsernin lainakanta, euroa/asukas, 2020 | Opetus- ja kulttuuritoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | Sosiaali- ja terveystoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 33 | Helsinki | 99.9 | 658457 | 0.2 | 14.3 | 68.1 | 17.6 | 5.6 | 10.3 | 1534 | ... | 398042 | 0.1 | 10.3 | 88.3 | 131.8 | 1314.3 | 1510.1 | 8451.7 | 2206.2 | 3396.6 |
| 11 | Espoo | 99.3 | 297132 | 1.5 | 18.4 | 66.4 | 15.2 | 6.7 | 13.0 | 1594 | ... | 122603 | 0.1 | 16.5 | 81.6 | 92.0 | 1039.7 | 4236.7 | 14637.8 | 2515.2 | 2866.7 |
| 267 | Tampere | 98.6 | 244223 | 1.3 | 13.1 | 67.7 | 19.3 | 0.5 | 5.2 | 114 | ... | 124149 | 0.2 | 17.2 | 81.4 | 119.8 | 703.1 | 3795.4 | 8936.4 | 2084.3 | 3544.2 |
| 289 | Vantaa | 99.7 | 239206 | 0.8 | 16.9 | 67.4 | 15.7 | 2.3 | 14.3 | 1181 | ... | 110704 | 0.2 | 23.4 | 75.0 | 102.5 | 702.9 | 3820.4 | 8292.2 | 2155.2 | 3115.6 |
| 179 | Oulu | 96.7 | 209551 | 1.1 | 17.1 | 66.1 | 16.9 | 0.2 | 3.4 | 632 | ... | 91589 | 0.6 | 19.1 | 79.3 | 104.8 | 465.0 | 3621.2 | 5928.8 | 2078.1 | 3319.4 |
| 275 | Turku | 99.1 | 195137 | 0.4 | 12.5 | 66.4 | 21.1 | 5.5 | 7.5 | -153 | ... | 98911 | 0.4 | 14.6 | 83.7 | 122.5 | 333.9 | 3666.7 | 7392.8 | 1954.9 | 3654.6 |
| 62 | Jyväskylä | 95.2 | 144473 | 0.7 | 14.9 | 66.2 | 19.0 | 0.2 | 3.5 | 213 | ... | 62971 | 0.6 | 16.9 | 81.1 | 107.4 | 500.6 | 2669.7 | 8552.4 | 1844.1 | 3159.0 |
| 113 | Kuopio | 86.5 | 121543 | 1.1 | 14.3 | 63.6 | 22.0 | 0.1 | 2.9 | -120 | ... | 52118 | 2.6 | 14.4 | 81.9 | 104.1 | 476.0 | 3822.5 | 9714.6 | 2052.0 | 3894.8 |
| 122 | Lahti | 97.5 | 120027 | 0.0 | 14.2 | 60.6 | 25.2 | 0.4 | 4.9 | -377 | ... | 48780 | 0.5 | 24.3 | 73.8 | 106.4 | 774.2 | 7281.9 | 10364.1 | 1971.8 | 3485.9 |
| 200 | Pori | 93.7 | 83482 | -0.2 | 13.7 | 59.6 | 26.7 | 0.6 | 2.9 | -406 | ... | 33086 | 1.4 | 19.0 | 78.3 | 103.3 | 385.8 | 3404.2 | 6792.6 | 1779.2 | 3683.1 |
10 rows × 33 columns
Helsinki loistaa listan kärjessä, väestön määrä on yli kaksinkertainen listan toisella sijalla olevaan kaupunkiin.
Koska koko data-aineistossa löytyy iso määrä muuttujia, niin voitaisiin tutkia hieman näiden korrelaatiota.
# Koska tällä hetkellä olemme kiinnostuneita määrällisten muuttujien välisestä riippuvuudesta,
# pudotetaan kuntien nimet
df_municipality = df_municipality.loc[:, ~df_municipality.columns.str.contains('Unnamed')]
#df_municipality.drop(['Kunta'], axis=1)
df_municipality.head()
| Taajama-aste, %, 2020 | Väkiluku, 2021 | Väkiluvun muutos edellisestä vuodesta, %, 2021 | Alle 15-vuotiaiden osuus väestöstä, %, 2021 | 15-64 -vuotiaiden osuus väestöstä, %, 2021 | Yli 64-vuotiaiden osuus väestöstä, %, 2021 | Ruotsinkielisten osuus väestöstä, %, 2021 | Ulkomaan kansalaisten osuus väestöstä, %, 2021 | Syntyneiden enemmyys, henkilöä, 2021 | Kuntien välinen muuttovoitto/-tappio, henkilöä, 2021 | ... | Alueella olevien työpaikkojen lukumäärä, 2020 | Alkutuotannon työpaikkojen osuus, %, 2020 | Jalostuksen työpaikkojen osuus, %, 2020 | Palvelujen työpaikkojen osuus, %, 2020 | Työpaikkaomavaraisuus, 2020 | Vuosikate, euroa/asukas, 2020 | Lainakanta, euroa/asukas, 2020 | Konsernin lainakanta, euroa/asukas, 2020 | Opetus- ja kulttuuritoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | Sosiaali- ja terveystoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 87.9 | 16467 | 0.5 | 16.3 | 58.9 | 24.8 | 0.2 | 1.9 | -15 | 64 | ... | 4432 | 3.1 | 33.8 | 61.4 | 67.4 | 1066.9 | 3199.6 | 4623.2 | 1801.7 | 3252.7 |
| 1 | 61.6 | 9311 | -1.1 | 16.9 | 53.5 | 29.5 | 0.1 | 2.7 | -45 | -93 | ... | 3302 | 11.5 | 27.2 | 59.4 | 100.0 | 599.7 | 2942.5 | 5437.3 | 2322.5 | 4142.8 |
| 2 | 51.6 | 2491 | -1.0 | 19.4 | 54.9 | 25.7 | 0.2 | 0.6 | -6 | -27 | ... | 704 | 22.4 | 21.3 | 54.4 | 72.1 | 783.1 | 3973.0 | 4469.2 | 2028.2 | 4153.8 |
| 3 | 60.8 | 11197 | -1.2 | 16.4 | 53.9 | 29.7 | 0.1 | 1.3 | -70 | -68 | ... | 4056 | 9.0 | 21.0 | 68.5 | 96.4 | 456.8 | 4029.7 | 7135.7 | 1990.8 | 4354.0 |
| 4 | 65.0 | 8033 | -0.3 | 13.3 | 52.4 | 34.3 | 0.2 | 1.9 | -72 | 27 | ... | 2282 | 8.6 | 30.7 | 57.9 | 79.5 | 1072.8 | 241.3 | 1623.5 | 1752.7 | 3559.3 |
5 rows × 32 columns
# Tarkastellaan muuttujien korrelaatiota suhteessa väkilukuun.
df_municipality.corr()['Väkiluku, 2021']
Taajama-aste, %, 2020 0.402412 Väkiluku, 2021 1.000000 Väkiluvun muutos edellisestä vuodesta, %, 2021 0.221529 Alle 15-vuotiaiden osuus väestöstä, %, 2021 0.054646 15-64 -vuotiaiden osuus väestöstä, %, 2021 0.497108 Yli 64-vuotiaiden osuus väestöstä, %, 2021 -0.336465 Ruotsinkielisten osuus väestöstä, %, 2021 -0.062596 Ulkomaan kansalaisten osuus väestöstä, %, 2021 0.254370 Syntyneiden enemmyys, henkilöä, 2021 0.655554 Kuntien välinen muuttovoitto/-tappio, henkilöä, 2021 -0.466797 Perheiden lukumäärä, 2020 0.999312 Asuntokuntien lukumäärä, 2021 0.998166 Rivi- ja pientaloissa asuvien asuntokuntien osuus, %, 2021 -0.640185 Vuokra-asunnoissa asuvien asuntokuntien osuus, %, 2020 0.606106 Vähintään toisen asteen tutkinnon suorittaneiden osuus 15 vuotta täyttäneistä, %, 2020 0.357167 Korkea-asteen tutkinnon suorittaneiden osuus 15 vuotta täyttäneistä, %, 2020 0.470151 Alueella asuvan työllisen työvoiman määrä, 2020 0.998574 Työllisyysaste, %, 2020 -0.083296 Asuinkunnassaan työssäkäyvien osuus, %, 2020 0.145967 Työttömien osuus työvoimasta, %, 2020 0.098807 Eläkeläisten osuus väestöstä, %, 2020 -0.323974 Taloudellinen huoltosuhde, 2020 -0.246306 Alueella olevien työpaikkojen lukumäärä, 2020 0.986236 Alkutuotannon työpaikkojen osuus, %, 2020 -0.341254 Jalostuksen työpaikkojen osuus, %, 2020 -0.081905 Palvelujen työpaikkojen osuus, %, 2020 0.348667 Työpaikkaomavaraisuus, 2020 0.253926 Vuosikate, euroa/asukas, 2020 0.057725 Lainakanta, euroa/asukas, 2020 0.021147 Konsernin lainakanta, euroa/asukas, 2020 0.228539 Opetus- ja kulttuuritoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 0.078696 Sosiaali- ja terveystoiminta yhteensä, nettokäyttökustannukset, euroa/asukas, 2020 -0.183148 Name: Väkiluku, 2021, dtype: float64
Data-aineistosta löytyi muutama mielenkiintoinen seikka mitä voitaisiin tutkia lisää, Korkea-asteen tutkinnon suorittaneiden sekä Rivi- ja pientaloissa asuvien asuntokuntien osuus suhteessa väestöön. Tehdään molemmista hajontakaavio jotta tämä suhde on helpompi visualisoida.
sns.jointplot(data=df_municipality, x='Korkea-asteen tutkinnon suorittaneiden osuus 15 vuotta täyttäneistä, %, 2020', y='Väkiluku, 2021', kind='reg')
<seaborn.axisgrid.JointGrid at 0x16593bde650>
sns.jointplot(data=df_municipality, x='Rivi- ja pientaloissa asuvien asuntokuntien osuus, %, 2021', y='Väkiluku, 2021', kind='reg')
<seaborn.axisgrid.JointGrid at 0x16591230450>
Voidaan todeta että näiden arvojen välillä on joko positiivinen tai negatiinen korrelaatio suhteessa väkilukuun. Koska kyseessä on prosenteista suhteessa väestöön, ei hajontakuvio ole niin rikkaan näköinen kuin aineistossa missä käytetään laajempaa numeraalista skaalaa, mutta joka tapauksessa voidaan todeta että valittujen arvojen välillä on yhteys väestön määrään.
Sales¶
Katsotaan viimeiseksi mottoriajoneuvojen myynti ja toimitus-dataa.
# Luetaan data-paketti. Huomioidaan että data on tällä kertaa .csv muodossa.
# Tiedossa on että paketin merkistökoodaus pitää erikseen määritellä, koskka Python-ohjelmointikieli ei oletuksella sitä tue.
df_sales = pd.read_csv(data_sales, encoding = 'ISO-8859-1')
# Tarastellaan mitä data-paketti sisältää
df_sales
| ORDERNUMBER | QUANTITYORDERED | PRICEEACH | ORDERLINENUMBER | SALES | ORDERDATE | STATUS | QTR_ID | MONTH_ID | YEAR_ID | ... | ADDRESSLINE1 | ADDRESSLINE2 | CITY | STATE | POSTALCODE | COUNTRY | TERRITORY | CONTACTLASTNAME | CONTACTFIRSTNAME | DEALSIZE | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 10107 | 30 | 95.70 | 2 | 2871.00 | 2/24/2003 0:00 | Shipped | 1 | 2 | 2003 | ... | 897 Long Airport Avenue | NaN | NYC | NY | 10022 | USA | NaN | Yu | Kwai | Small |
| 1 | 10121 | 34 | 81.35 | 5 | 2765.90 | 5/7/2003 0:00 | Shipped | 2 | 5 | 2003 | ... | 59 rue de l'Abbaye | NaN | Reims | NaN | 51100 | France | EMEA | Henriot | Paul | Small |
| 2 | 10134 | 41 | 94.74 | 2 | 3884.34 | 7/1/2003 0:00 | Shipped | 3 | 7 | 2003 | ... | 27 rue du Colonel Pierre Avia | NaN | Paris | NaN | 75508 | France | EMEA | Da Cunha | Daniel | Medium |
| 3 | 10145 | 45 | 83.26 | 6 | 3746.70 | 8/25/2003 0:00 | Shipped | 3 | 8 | 2003 | ... | 78934 Hillside Dr. | NaN | Pasadena | CA | 90003 | USA | NaN | Young | Julie | Medium |
| 4 | 10159 | 49 | 100.00 | 14 | 5205.27 | 10/10/2003 0:00 | Shipped | 4 | 10 | 2003 | ... | 7734 Strong St. | NaN | San Francisco | CA | NaN | USA | NaN | Brown | Julie | Medium |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2818 | 10350 | 20 | 100.00 | 15 | 2244.40 | 12/2/2004 0:00 | Shipped | 4 | 12 | 2004 | ... | C/ Moralzarzal, 86 | NaN | Madrid | NaN | 28034 | Spain | EMEA | Freyre | Diego | Small |
| 2819 | 10373 | 29 | 100.00 | 1 | 3978.51 | 1/31/2005 0:00 | Shipped | 1 | 1 | 2005 | ... | Torikatu 38 | NaN | Oulu | NaN | 90110 | Finland | EMEA | Koskitalo | Pirkko | Medium |
| 2820 | 10386 | 43 | 100.00 | 4 | 5417.57 | 3/1/2005 0:00 | Resolved | 1 | 3 | 2005 | ... | C/ Moralzarzal, 86 | NaN | Madrid | NaN | 28034 | Spain | EMEA | Freyre | Diego | Medium |
| 2821 | 10397 | 34 | 62.24 | 1 | 2116.16 | 3/28/2005 0:00 | Shipped | 1 | 3 | 2005 | ... | 1 rue Alsace-Lorraine | NaN | Toulouse | NaN | 31000 | France | EMEA | Roulet | Annette | Small |
| 2822 | 10414 | 47 | 65.52 | 9 | 3079.44 | 5/6/2005 0:00 | On Hold | 2 | 5 | 2005 | ... | 8616 Spinnaker Dr. | NaN | Boston | MA | 51003 | USA | NaN | Yoshido | Juri | Medium |
2823 rows × 25 columns
Data-paketissa on hyvin aineistoa mutta jos keskittyisimme maakohtaisiin tuloksiin ja näin ollen voisimme poistaa turhia sarakkeita jotta kokonaisuus on hallittavampi.
df_sales.drop(['ORDERLINENUMBER','ORDERDATE','CUSTOMERNAME', 'ADDRESSLINE1', 'PHONE', 'ADDRESSLINE2', 'CITY', 'STATE', 'POSTALCODE', 'TERRITORY', 'CONTACTLASTNAME', 'CONTACTFIRSTNAME','QTR_ID','MONTH_ID','MSRP', 'PRODUCTCODE'], axis='columns', inplace=True)
df_sales
| ORDERNUMBER | QUANTITYORDERED | PRICEEACH | SALES | STATUS | YEAR_ID | PRODUCTLINE | COUNTRY | DEALSIZE | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 10107 | 30 | 95.70 | 2871.00 | Shipped | 2003 | Motorcycles | USA | Small |
| 1 | 10121 | 34 | 81.35 | 2765.90 | Shipped | 2003 | Motorcycles | France | Small |
| 2 | 10134 | 41 | 94.74 | 3884.34 | Shipped | 2003 | Motorcycles | France | Medium |
| 3 | 10145 | 45 | 83.26 | 3746.70 | Shipped | 2003 | Motorcycles | USA | Medium |
| 4 | 10159 | 49 | 100.00 | 5205.27 | Shipped | 2003 | Motorcycles | USA | Medium |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2818 | 10350 | 20 | 100.00 | 2244.40 | Shipped | 2004 | Ships | Spain | Small |
| 2819 | 10373 | 29 | 100.00 | 3978.51 | Shipped | 2005 | Ships | Finland | Medium |
| 2820 | 10386 | 43 | 100.00 | 5417.57 | Resolved | 2005 | Ships | Spain | Medium |
| 2821 | 10397 | 34 | 62.24 | 2116.16 | Shipped | 2005 | Ships | France | Small |
| 2822 | 10414 | 47 | 65.52 | 3079.44 | On Hold | 2005 | Ships | USA | Medium |
2823 rows × 9 columns
Koska data on suurilta osin Englannin-kielistä, pidetään se sellaisena mutta siistitään hieman sarakkeiden nimiä.
# Muutetaan nimet olemaan pienellä fontilla mutta isolla alkukirjaimella.
t = df_sales.columns
rename_dic = {}
for x in t:
s = x
s = s.lower()
ts = s[0].upper() + s[1:]
rename_dic[x] = str(ts)
# Tehdään muutokset suoraan dataframeen ei luoda uutta dataframea.
df_sales.rename(columns = rename_dic, inplace=True)
# Tarkastetaan muutokset
df_sales
| Ordernumber | Quantityordered | Priceeach | Sales | Status | Year_id | Productline | Country | Dealsize | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 10107 | 30 | 95.70 | 2871.00 | Shipped | 2003 | Motorcycles | USA | Small |
| 1 | 10121 | 34 | 81.35 | 2765.90 | Shipped | 2003 | Motorcycles | France | Small |
| 2 | 10134 | 41 | 94.74 | 3884.34 | Shipped | 2003 | Motorcycles | France | Medium |
| 3 | 10145 | 45 | 83.26 | 3746.70 | Shipped | 2003 | Motorcycles | USA | Medium |
| 4 | 10159 | 49 | 100.00 | 5205.27 | Shipped | 2003 | Motorcycles | USA | Medium |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2818 | 10350 | 20 | 100.00 | 2244.40 | Shipped | 2004 | Ships | Spain | Small |
| 2819 | 10373 | 29 | 100.00 | 3978.51 | Shipped | 2005 | Ships | Finland | Medium |
| 2820 | 10386 | 43 | 100.00 | 5417.57 | Resolved | 2005 | Ships | Spain | Medium |
| 2821 | 10397 | 34 | 62.24 | 2116.16 | Shipped | 2005 | Ships | France | Small |
| 2822 | 10414 | 47 | 65.52 | 3079.44 | On Hold | 2005 | Ships | USA | Medium |
2823 rows × 9 columns
Päivitetään vielä hieman nimiä
df_sales.rename(columns = {'Ordernumber': 'Order number', 'Quantityordered':'Quantity ordered', 'Priceeach':'Price for each', 'Year_id':'Year', 'Productline':'Product line','Dealsize':'Deal size'}, inplace=True)
df_sales
| Order number | Quantity ordered | Price for each | Sales | Status | Year | Product line | Country | Deal size | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 10107 | 30 | 95.70 | 2871.00 | Shipped | 2003 | Motorcycles | USA | Small |
| 1 | 10121 | 34 | 81.35 | 2765.90 | Shipped | 2003 | Motorcycles | France | Small |
| 2 | 10134 | 41 | 94.74 | 3884.34 | Shipped | 2003 | Motorcycles | France | Medium |
| 3 | 10145 | 45 | 83.26 | 3746.70 | Shipped | 2003 | Motorcycles | USA | Medium |
| 4 | 10159 | 49 | 100.00 | 5205.27 | Shipped | 2003 | Motorcycles | USA | Medium |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2818 | 10350 | 20 | 100.00 | 2244.40 | Shipped | 2004 | Ships | Spain | Small |
| 2819 | 10373 | 29 | 100.00 | 3978.51 | Shipped | 2005 | Ships | Finland | Medium |
| 2820 | 10386 | 43 | 100.00 | 5417.57 | Resolved | 2005 | Ships | Spain | Medium |
| 2821 | 10397 | 34 | 62.24 | 2116.16 | Shipped | 2005 | Ships | France | Small |
| 2822 | 10414 | 47 | 65.52 | 3079.44 | On Hold | 2005 | Ships | USA | Medium |
2823 rows × 9 columns
Nyt listan sisälty näkyy paremmin. Tarkastetaan myynti vuosien mukaan.
df_sales.pivot_table(values='Sales', index='Year', aggfunc='sum').style.format(precision=0)
| Sales | |
|---|---|
| Year | |
| 2003 | 3516980 |
| 2004 | 4724163 |
| 2005 | 1791487 |
Myynin osalta näyttää siltä että vuosi 2005 on ollut huono vuosi, tai sitten data-aineiston päiväys on kyseiseltä vuodelta, jolloin tilikausi voi olla vielä kesken tai kaikki myyntitapahtumat eivät ole vielä realisoituneet. Myynnin keskiarvo voisi olla ehkä hieman kuvaavampi.
df_sales.pivot_table(values='Sales', index='Year').style.format(precision=0)
| Sales | |
|---|---|
| Year | |
| 2003 | 3517 |
| 2004 | 3512 |
| 2005 | 3748 |
Myynninkeskiarvon osalta 2005 vuosi näyttää edustavan hyvää kehitystä. Tulee tosin huomioida että kuten aikaisemmin tuotiin esiin 2005 vuoden myynnin vähäisyys, voi olla että luvuissa on vasta osa vuoden 2005 myynnistä ja näiden osalta mukana olisi isompia tilauksia.
Tarkastellaan seuraavaksi maakohtaista myyntiä tuotelinjan mukaisesti.
df_sales.pivot_table(values='Sales', index='Country', columns='Product line').style.format(precision=0, na_rep='-').highlight_max(color='lightgreen', axis=0).highlight_min(color='pink', axis=0)
| Product line | Classic Cars | Motorcycles | Planes | Ships | Trains | Trucks and Buses | Vintage Cars |
|---|---|---|---|---|---|---|---|
| Country | |||||||
| Australia | 3643 | 3460 | 2994 | 2080 | 1681 | 3866 | 3268 |
| Austria | 4058 | 5210 | 2977 | 2256 | - | 4095 | 2720 |
| Belgium | 5034 | - | 5625 | 2883 | 3006 | - | 2995 |
| Canada | 4402 | 4177 | 2551 | 2879 | - | 3247 | 2701 |
| Denmark | 4623 | - | 3793 | 2764 | 2869 | 4794 | 3015 |
| Finland | 4041 | 3682 | 2865 | 3312 | 2559 | 3680 | 2626 |
| France | 3969 | 3329 | 3380 | 3166 | 3906 | 3899 | 3045 |
| Germany | 4120 | 2499 | 2875 | 2750 | 2522 | 5089 | 2326 |
| Ireland | 5281 | 2477 | 2946 | - | 1556 | 3983 | 2234 |
| Italy | 4592 | 3784 | 3167 | 2951 | 2092 | 2957 | 2694 |
| Japan | 5909 | 2948 | 3074 | 3772 | 1762 | 4450 | 3272 |
| Norway | 3851 | 3698 | 2682 | - | 5655 | 4120 | 3073 |
| Philippines | 4086 | 2580 | 4181 | - | - | - | 1935 |
| Singapore | 4153 | 4176 | - | 3539 | 2656 | 3871 | 2497 |
| Spain | 3968 | 3928 | 3000 | 3191 | 3098 | 3860 | 3102 |
| Sweden | 4064 | 5189 | 2967 | 3092 | 3808 | 4357 | 2817 |
| Switzerland | 3797 | - | - | - | - | - | - |
| UK | 3465 | 4534 | 2744 | 3172 | 3159 | 3518 | 3174 |
| USA | 4087 | 3492 | 3457 | 2996 | 2770 | 3552 | 3383 |
Pivot-taulusta näkee hyvin myynnin hajontaa. Huomion arvoista on myös se että kaikkiin maihin ei osteta kaikkia tuotelinjone tuotteita, Sveitsiin myydään syystä tai toisesta ainoastaa klassisia autoja.
Tarkastellaan miten myynti jakautuu kokonaisuudessaan maakohtaisesti.
df_sales_country = df_sales.pivot_table(values='Sales', index='Country', aggfunc=sum).sort_values(by='Sales', ascending=False)
df_sales_country['% of sales'] = round((df_sales_country['Sales']/df_sales_country['Sales'].sum())*100,2)
print(df_sales_country)
Sales % of sales Country USA 3627982.83 36.16 Spain 1215686.92 12.12 France 1110916.52 11.07 Australia 630623.10 6.29 UK 478880.46 4.77 Italy 374674.31 3.73 Finland 329581.91 3.29 Norway 307463.70 3.06 Singapore 288488.41 2.88 Denmark 245637.15 2.45 Canada 224078.56 2.23 Germany 220472.09 2.20 Sweden 210014.21 2.09 Austria 202062.53 2.01 Japan 188167.81 1.88 Switzerland 117713.56 1.17 Belgium 108412.62 1.08 Philippines 94015.73 0.94 Ireland 57756.43 0.58
C:\Users\ter\AppData\Local\Temp\ipykernel_22448\3733902755.py:1: FutureWarning: The provided callable <built-in function sum> is currently using DataFrameGroupBy.sum. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "sum" instead. df_sales_country = df_sales.pivot_table(values='Sales', index='Country', aggfunc=sum).sort_values(by='Sales', ascending=False)
Yhdysvallat edustaa myynnin osalta selkeästi isointa myyntimaata.
Tarkastetaan vielä mikä tuotelinja on myynninosalta menestykseikkäin.
df_sales.pivot_table(values='Sales', index='Product line', aggfunc=sum).sort_values(by='Sales', ascending=False).style.format(precision=0)
C:\Users\ter\AppData\Local\Temp\ipykernel_22448\3088610839.py:1: FutureWarning: The provided callable <built-in function sum> is currently using DataFrameGroupBy.sum. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "sum" instead. df_sales.pivot_table(values='Sales', index='Product line', aggfunc=sum).sort_values(by='Sales', ascending=False).style.format(precision=0)
| Sales | |
|---|---|
| Product line | |
| Classic Cars | 3919616 |
| Vintage Cars | 1903151 |
| Motorcycles | 1166388 |
| Trucks and Buses | 1127790 |
| Planes | 975004 |
| Ships | 714437 |
| Trains | 226243 |
Voidaan todeta että klassiset autot edustavat myynnin arvon perusteella menestyksekkäintä tuoteryhmää.