In [251]:
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.

In [252]:
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.

In [253]:
## 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
Out[253]:
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

In [254]:
## 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

In [255]:
# Otetaan yleinen kuva data-aineistosta
df_titanic.describe()
Out[255]:
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.

In [256]:
# 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
Out[256]:
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
In [257]:
# 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} %'})
Out[257]:
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.

In [258]:
# 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)
No description has been provided for this image

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.

In [259]:
#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()
Out[259]:
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.

In [260]:
# 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} %'})
Out[260]:
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.

In [261]:
# 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()
Out[261]:
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)
In [262]:
# 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}')
Out[262]:
Text(0, 0.5, '%, n = 1046')
No description has been provided for this image

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.

In [263]:
# 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
Out[263]:
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.

In [264]:
# 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
Out[264]:
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
In [265]:
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)
No description has been provided for this image

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.

In [266]:
# Aloitetaan lukemalla Excel-tiedosto
df_municipality = pd.read_excel(data_kunnat)

# Tarkastellaan hieman mitä data aineisto sisältää
df_municipality
Out[266]:
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

In [267]:
# Tarkastellaan vielä hieman tunnuslukuja
df_municipality.describe()
Out[267]:
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.

In [268]:
# Napataan 10 suurinta kuntaa väkiluvun perusteella ja tallennetaan se uuteen data-frameen. 
df_municipality.nlargest(10,'Väkiluku, 2021')
Out[268]:
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.

In [269]:
# 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()
Out[269]:
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

In [270]:
# Tarkastellaan muuttujien korrelaatiota suhteessa väkilukuun.
df_municipality.corr()['Väkiluku, 2021']
Out[270]:
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.

In [271]:
sns.jointplot(data=df_municipality, x='Korkea-asteen tutkinnon suorittaneiden osuus 15 vuotta täyttäneistä, %, 2020', y='Väkiluku, 2021', kind='reg')
Out[271]:
<seaborn.axisgrid.JointGrid at 0x16593bde650>
No description has been provided for this image
In [272]:
sns.jointplot(data=df_municipality, x='Rivi- ja pientaloissa asuvien asuntokuntien osuus, %, 2021', y='Väkiluku, 2021', kind='reg')
Out[272]:
<seaborn.axisgrid.JointGrid at 0x16591230450>
No description has been provided for this image

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.

In [273]:
# 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
Out[273]:
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.

In [274]:
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
Out[274]:
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ä.

In [275]:
# 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
Out[275]:
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ä

In [276]:
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
Out[276]:
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.

In [277]:
df_sales.pivot_table(values='Sales', index='Year', aggfunc='sum').style.format(precision=0)
Out[277]:
  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.

In [278]:
df_sales.pivot_table(values='Sales', index='Year').style.format(precision=0)
Out[278]:
  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.

In [279]:
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)
Out[279]:
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.

In [293]:
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.

In [280]:
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)
Out[280]:
  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ää.