Datajournalismikurssin materiaalit ja ohjeet

Kurssimateriaalit ovat tässä verkko-osoitteessa. Tampereen yliopiston datajournalismi ka ohjelmointi -kurssi, materiaalit 2024.

Kurssin materiaalia päivitetään verkkosivulle joka viikko.

Sisällysluettelo


# Python koodi esimerkki
def hello_world():
    print("Hello, World!")

hello_world()
      

Viikko 1

Ohjelmointi, komentorivi ja datan käyttö

Miksi ohjelmointia on hyvä ymmärtää?

  • Koodin ymmärtäminen auttaa hahmottamaan yhä teknisempää yhteiskuntaa. Yhteiskunta ja arkipäiväiset toiminnot digitalisoituvat jatkuvasti. Koodin perusteiden ymmärtäminen auttaa arvioimaan teknologian roolia ja vaikutuksia yhteiskunnassa.
  • Ohjelmointi on luova tapa ratkaista ongelmia ja tuoda omia ideoita käytäntöön. Koodin avulla voit kehittää uusia työkaluja, luoda vuorovaikutteisia kokemuksia ja vaikuttaa ympäristöösi uusin keinoin.
  • Kun ymmärrät koodia, sinulla on vapaus käyttää ja muokata avoimen lähdekoodin projekteja omiin tarpeisiisi. Tämä antaa mahdollisuuden rakentaa omaa osaamista ja riippumattomuutta kaupallisista ohjelmistoratkaisuista, sekä tukea yhteisöllisessä kehittämisessä.

ensimmäinen luento, alkeet


2 + 2
    

200 - 75
    

haravia_luku = 10
haravia_luku * (haravia_luku + 2)
    

Tehokas laskemaan isompiakin lukuja


# Yksinkertainen laskutoimitus
2 + 3
  

# Vähennyslasku
250 - 80
  

# Kertolasku sulkeilla
5 * (4 + 8)
  

# Jakolasku sulkeilla
9 / (4 + 10)
  

# Tämä on haastavampi laskutoimitus
1423345 * 317123
  

# Alla oleva koodia ei suoriteta, koska se on kommentoitu pois
# 3 + 3
  

soitto = 16
soitto * soitto  # Muuttujan käyttö on voimakas tapa 
# hallita koodia. Laskemalla voi kokeilla, kuinka monta 
# saa soiton puhelimeen jos 16 henkilöä soittaa 16 henkilölle
  

haravia_lukumaara = 5
haravia_lukumaara * (haravia_lukumaara + 3)
# Koodi suoritetaan matemaattisesti järjestyksessä:
# ensin sulkeet, sitten lasketaan kertolasku.
  

Matematiikan laskutoimitukset

Matemaattinen sana Symboli Esimerkki Vastaus
Summa + 5 + 2 7
Vähennys - 5 - 2 3
Kertolasku * 5 * 2 10
Jakolasku / 5 / 2 2.5
Potenssi ** 5 ** 2 25
Jakojäännös % 5 % 2 1

'Tiina'
  

"Laura"
  

# Nimimuuttuja
nimi = "Satu"
  

# Näytetään muuttujan arvo
nimi
  

nimi = "Maria"
  

# Tulostetaan nimi
print(nimi)
  

# Yhdistetään tekstiä
nimi = "Satu"
print("Hei " + nimi + "!")
  

# Useita arvoja, eroteltuna huutomerkein
print("Hei", "Moi", "Terve", sep="! ", end="!")
  

# Tutkitaan luvun tyyppiä
luku = 3
type(luku)
  

# Tutkitaan tekstimuuttujan tyyppiä
nimi = "Satu"
type(nimi)
  

totuusarvo = True
type(totuusarvo)
#tulostaa rivin 
  

soitto = 14

# Huom! Sisennyksellä on merkitystä
if soitto > 10:
    print("Luku on suurempi kuin kymmenen!")
else:
    print("Luku on pienempi kuin kymmenen")
  

# Ehtolauseella useita vaihtoehtoja
luku = 9

if luku < 5:
    print("Luku on pienempi kuin viisi.")
elif luku == 5:
    print("Luku on viisi.")
else:
    print("Luku on suurempi kuin viisi.")
  

# Tarkistetaan arvojen väli
luku = 7

if luku \> 0 and luku <= 12:
    print("Luku on yhdestä kahteentoista.")
else:
    print("Luku on jotain muuta kuin yhdestä kahteentoista.")

  

# Sama tarkistus toisin tavoin
luku = 5

if 0 < luku <= 10:
    print("Luku on yhdestä kymmeneen.")
else:
    print("Luku on jotain muuta kuin yhdestä kymmeneen.")
  
# Funktio, joka tervehtii nimellä

# Yksinkertainen funktio tervehtimään
def hei():
    print("Hei, maailma!")

hei()
  

# Funktio, joka tervehtii nimellä
def tervehdys(nimi):
    print("Hei " + nimi + "!")

tervehdys("Ella")
  

# Funktio, jossa on oletusnimi
def tervehdys(nimi="vieras"):
    print("Hei " + nimi + "!")

tervehdys()
  

# Kaksinkertaistava funktio
def tuplaus(luku):
    return luku * 2

print(tuplaus(7))
  

# Funktio, joka tervehtii innokkaasti tai vähemmän innokkaasti
def tervehdys(nimi, innostunut):
    if innostunut:
        return "Hei " + nimi + "! On ilo nähdä sinut täällä!"
    else:
        return "Hei " + nimi + ". Kiva että tulit."

print(tervehdys("Laura", True))
  

# Hahmotellaan ensimmäinen kirjain nimestä
nimi = "Satu"
alkukirjain = nimi[0]
print(alkukirjain)
  

# Listan pituus
lista = [2, 3, 6]
print(len(lista))
  

# Listan ensimmäinen elementti
lista = [3, "merkkejä", True]
print("Listan ensimmäinen asia on", lista[0])
  

# Monikon ensimmäinen asia
monikko = (3, "dataa", False)
print("Monikon ensimmäinen asia on", monikko[0])
  

# Sanakirjan arvojen tarkastelua
sanakirja = {"avain": "arvo"}
print(sanakirja["avain"])
  

# Sanakirjan tekstin tarkistaminen
sanakirja = {"asia": "Tässä on tekstiä."}
print(sanakirja["asia"])
  

# Käyttäjän antama syöte
palaute = input()
print("Kirjoitit juuri:", palaute)
  

# Kielen valinta sanakirjasta
sanakirja = {"hei": "hello"}

kielivalinta = input("valitse suomi tai englanti: ")

if kielivalinta == "englanti":
    print(sanakirja["hei"])
else:
    print("hei")
  

# Keskustelijafunktio
def keskustelija():
    sanottu_asia = input("hei")
    if sanottu_asia == "hei":
        print("🤖 Tervehdys!")
    else:
        print("🤖 Non intellego te. 🙌")

keskustelija()
  

Millaisia tapoja on suorittaa Python-koodia?

Yksi tärkeimmistä työkaluista jokaiselle Python-ohjelmoijalle on interaktiivinen Python-tulkki.

Tulkin käynnistäminen voi riippua alustastasi. Linux- tai Mac-järjestelmässä voit kirjoittaa python3 terminaaliin. Windowsissa komento komentorivillä voi olla python.

Voit myös kokeilla selaimessa toimivaa Python-tulkkiä, kuten https://www.python.org/shell/.

Tulkki on tapa suorittaa Python-koodia rivi riviltä heti, kun kirjoitat sen. Kun kirjoitat rivin koodia ja painat Enter voit suorittaa rivin. Uusimmassa Python 3.13 -versiossa voi käyttää lohkoja kopioidessa/liittäessä koodia ja suorittaa useita rivejä koodeja kerrallaan.

Pythonin kieli toimii samalla tavoin kun Python-ohjelman asentaa tietokoneelle. Mikä tahansa Python-koodi, joka voidaan kirjoittaa tulkkiin, voidaan myös kirjoittaa tiedostoon. Tiedostoihin ja tallentamiseen pääsemme seuraavilla viikoilla. Seuraavalla viikolla on hieman esimakua tulevasta Jupyter-ympäristöstä.


Tässä esimerkissä ohjelma kysyy käyttäjän nimen ja iän, ja antaa tietoa vastauksien perusteella. Kopioi lohkot 1-3:een yksi kerrallaan interaktiiviseen komentotulkkiin ja suorita ohjelma. Voit myös kirjoittaa kaikki komentotulkkiin kerralla yhteen, jos haluat.

osa 1


# Tämä ohjelma sanoo hei ja kysyy nimen.

print("Hei, maailma!")

print("Mikä on nimesi?")    # kysytään nimi

minunNimeni = input()
  

osa 2


print("Mukava tavata sinut, " + minunNimeni)
print("Nimesi pituus on:")
print(len(minunNimeni))
print("Kuinka vanha olet?")    # kysytään ikä
minunIkäni = input()

  

osa 3


print("Olet " + str(int(minunIkäni) + 1) + " vuotta vanha vuoden päästä.")
  

Viikko 2 esimakua

Vaikka interaktiivinen komentorivi on hyvä yksittäisten Python-käskyjen suorittamiseen, kokonaisen Python-ohjelman kirjoittamista varten ohjeet kirjoitetaan kurssilla Työkirjaan JupyterLiteen.

JupyterLiten käyttö on samanlaista kuin tekstieditoreiden, kuten Muistion tai VSCoden, mutta siinä on erityisiä ominaisuuksia grafiikan ja kommenttien kirjoittamiseen. Avaa uusi tiedosto JupyterLite:ssa klikkaamalla yläriviltä "+"-painiketta ja valitsemalla Python (Pyodide).

Avautuvassa ikkunassa näkyy vilkkuva kursori, joka odottaa syötettäsi. Tämä eroaa interaktiivisesta komentorivistä, joka suorittaa Python-komennot heti, kun painat ENTER-näppäintä. JupyterLitessä voit kirjoittaa useita komentoja ja suorittaa koko ohjelman kerralla. Tässä on tapa erottaa nämä kaksi:

  • Interaktiivisessa komentorivissä on aina `>>>`-kehotus.
  • Komentorivillä ajettaessa (tai Jupyterissä) ikkunassa ei ole `>>>`-kehotusta.

Kuinka tullaan taitavammaksi Python-ohjelmoijaksi?

Kuten moni fiksu aikaisemmista Pythonin opettajista journalisteille on sanonut, paremmaksi tullaan harjoittelemalla. Tee projekteja, ja toista niitä. Tässä on esimerkiksi yksi neuvo, jota käytetään Yhdysvalloissa New Yorkin täydennyskoulutuksessa, jonne ihmisiä lähtee Suomesta oppimaan datajournalismia: Aloita projekti. Harjoittele, kokeile ja tee virheitä. Tee yksi asia kerrallaan. (Jonathan Soma). Voit edellisessä linkissä myös kokeilla yhtä haastavampaa harjoitusta Projektina, Moon Measurer (harjoitus on vapaaehtoinen, tästä et saa tehtäväpisteitä).

Tietorakenteet lyhyesti

Listat

Lista on tietorakenne, joka voi tallentaa kokoelman kohteita. Se on yksi sisäänrakennetuista tietotyypeistä ja sitä käytetään yleisesti järjestetyn alkiojoukon tallentamiseen. Listat voivat sisältää eri tietotyyppisiä alkioita, kuten numeroita, merkkijonoja ja jopa muita listoja.

Listojen keskeiset ominaisuudet

👉 Listat säilyttävät alkioiden järjestyksen niiden lisäämisen mukaan, jolloin voit käyttää alkioita niiden indeksin mukaan.

👉 Voit muokata listan sisältöä lisäämällä tai poistamalla alkioita.

👉 Listat voivat kasvaa tai kutistua tarpeen mukaan. Voit lisätä tai poistaa alkioita määrittelemättä kokoa etukäteen.

Listojen luominen

mixed_list = [1, "hello", 3.14, True]

Listan elementtien valinta

print(numbers[0])   # 1
print(fruits[2])    # banana
print(mixed_list[1])  # hello

Tuple

Tuple on järjestetty, muuttumaton kokoelma elementtejä. Tämä tarkoittaa, että kun olet luonut tuplen, et voi muokata sen sisältöä - et voi lisätä, poistaa tai muuttaa elementtejä tuplessa sen luomisen jälkeen. Tuplet määritellään sulkeilla () ympäröidyllä pilkkuerotellulla arvojoukolla.

Perussyntaksi

my_tuple = (1, 2, 3, 'hello', 3.14)
print(my_tuple[0])  # Tulostus: 1
print(my_tuple[3])  # Tulostus: 'hello'

Virhe tietojoukon tuple lisäyksissä → tuplen ominaisuus

my_tuple = (1, 2, 3, 'hello', 3.14)

Tämä aiheuttaa virheen, koska tuplet ovat muuttumattomia

my_tuple[0] = 5

Luodaan uusi tuple muutetulla sisällöllä

new_tuple = my_tuple + (5, 'world')
print(new_tuple)  # Tulostus: (1, 2, 3, 'hello', 3.14, 5, 'world')

Sanakirja

Sanakirja on sisäänrakennettu tietotyyppi, joka edustaa avain-arvoparien kokoelmaa. Se on erittäin joustava ja tehokas tietorakenne, jota käytetään avaamien määrittelemiseksi arvoille.

Sanakirjojen keskeiset ominaisuudet

👉 Jokainen alkio sanakirjassa koostuu avaimeista ja sen vastaavasta arvosta. Avain on ainutkertainen tunniste arvolle.

👉 Toisin kuin listat, sanakirjat ovat järjestämättömiä kokoelmia, mikä tarkoittaa, että alkioiden järjestystä ei taata.

👉 Sanakirjoja voidaan muokata luomisen jälkeen. Voit lisätä, poistaa tai päivittää avain-arvopareja.

👉 Sanakirjat voivat kasvaa tai kutistua tarpeen mukaan.

👉 Jokaisen sanakirjan avaimen on oltava ainutkertainen. Jos yrität lisätä avaimen, joka jo on olemassa, uusi arvo ylikirjoittaa olemassa olevan.

Tyhjä sanakirja

empty_dict = {}

Sanakirja avain-arvopareilla

student_info = {'name': 'Alice', 'age': 20, 'grade': 'A'}

dict() Konstruktorin käyttäminen

person = dict(name='Bob', age=25, city='London')

Sanakirja eri tietotyypeillä

mixed_dict = {'name': 'Charlie', 'age': 30, 'grades': [85, 90, 78], 'is_student': True}

Sisäkkäinen sanakirja

nested_dict = {'person': {'name': 'Antoan', 'age': 22}, 'location': {'city': 'Paris', 'country': 'France'}}

Lista tuplista

tuple_list = [('name', 'Mikael'), ('age', 20), ('city', 'Berlin')]
from_tuples_dict = dict(tuple_list)

Joukot

Joukko on järjestämätön kokoelma ainutlaatuisia elementtejä. Joukot määritellään sulkemalla pilkulla erotettu arvojono aaltosulkeiden sisään. Toisin kuin listat tai tuplet, joukot eivät salli päällekkäisiä elementtejä, eikä elementtien järjestystä taata.

Esimerkki joukosta ("set"-niminen tietorakenne englanniksi)

my_set = {1, 2, 3, 4, 5}

Voimme myös luoda joukon listasta käyttämällä set()-rakentajaa

my_list = [1, 2, 2, 3, 4, 4, 5]
converted_set = set(my_list)
print(converted_set)  # Output: {1, 2, 3, 4, 5}

Funktiot kertaus

Funktio on uudelleenkäytettävä koodilohko, joka suorittaa tietyn tehtävän tai joukon tehtäviä. Voimme määritellä funktion käyttämällä "def"-avainsanaa.

Funktion perussyntaksi
def greet():
    print("Hello From Function")
    
#Funktion kutsuminen
   
greet()

greet()
greet()

#Toinen yksinkertainen esimerkki
def printNumber():
  result = 2 + 4
  print(result)

printNumber()

Moduulit

Moduuli on tiedosto, joka sisältää Python-koodia. Tämä koodi voi määritellä funktioita, luokkia ja muuttujia. Moduulit auttavat järjestämään liittyvän koodin tiedostoiksi, joita voidaan helposti käyttää uudelleen ja tuoda muihin Python-skripteihin.

Pythonin standardikirjasto on kokoelma moduuleja, jotka tarjoavat käyttövalmiita toimintoja tehtäviin kuten tiedostojen syöttö ja tulostus, verkottuminen ja paljon muuta.

Koko Moduuli

import module_name

Tuo aliaksena

import module_name as alias_name

Tietty kohde

from module_name import item_name

Tuo tietty kohde moduulista ja anna sille alias

from module_name import item_name as alias_name

Kaikki kohteet

from module_name import *

Esimerkki osoitteessa tuotuja_standardikirjastoja_pythoniin

Uudelleen käytettävää koodia

  • Moduuli (module): Koodia tiedostossa
  • Paketti (package): Kokoelma moduuleja
  • Kirjasto (library): Kokoelma paketteja Apua data-analyysiin: pandas

Pandas

“pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool, built on top of the Python programming language.”

Asennus: pip install pandas

Kehitysympäristön kysymyksiä

  • Missä koodi on? (oma tietokone vs. pilvipalvelu)
  • Mihin kirjastot asennetaan?
  • Kielen ja kirjastojen eri versioiden yhteensopivuus
  • Skriptejä (komentosarjoja) vai muistikirjoja?

Csv-tiedoston lukeminen kirjaston avulla: pd.read_csv

import pandas as pd

df = pd.read_csv("data/aineisto_ote.csv")

df
Vaalipiiri Puolue
0 Uudenmaan vaalipiiri Kokoomus
1 Uudenmaan vaalipiiri Suomen Kommunistinen Puolue
2 Uudenmaan vaalipiiri Perussuomalaiset

type(df)

pandas.core.frame.DataFrame


type(df["vaalipiiri"])

pandas.core.series.Series

Uudet käsitteet

  • DataFrame: “2-dimensional labeled data structure with columns of potentially different types”
  • Series: “One-dimensional labeled array capable of holding any data type (integers, strings, floating point numbers, Python objects, etc.)”
  • Taulukoita ja sarakkeita!
  • Funktioita ja ominaisuuksia, jotka listattu kirjaston dokumentaatiossa
  • Esimerkkejä dokumentaatiosta pandas.read_csv pandas.read_excel

Välissä toimivia vinkkejä siihen, miten tutkit muuttujaa kooditulkissa

Jos tarvitset jonkin metodin ja melkein muistat sen nimen, voi joskus olla nopeampaa ohittaa Google ja käyttää dir-funktiota tulkissa. Se kertoo, mitkä menetelmät ovat käytettävissä annetussa objektissa:

>>> dir("tämä on merkkijono")
['__add__', '__class__', '__contains__', '__delattr__', '__dir__',
'__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__gt__',
'__hash__', '__init__', '__init_subclass__', '__iter__', '__le__',
'__len__', '__lt__',
'__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__',
'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith',
'expandtabs', 'find',
'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii',
'isdecimal', 'isdigit',
'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace',
'istitle', 'isupper', 'join',
'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace',
'rfind', 'rindex', 'rjust','rpartition', 'rsplit', 'rstrip', 'split',
'splitlines', 'startswith', 'strip', 'swapcase',
'title', 'translate', 'upper', 'zfill']

Python-merkkijonoilla on paljon käytettävissä olevia metodeja, kuten näette yllä. Tässä vaiheessa voi olla parasta jättää huomiotta kaikki metodit, joiden nimissä on alaviivoja, mutta loput voivat osoittautua hyödyllisiksi. Joidenkin toimintaperiaatteen voit selvittää kokeilemalla niitä, ja loput voit etsiä verkosta.

Python-listoilla ei ole aivan niin paljon metodeja:

>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__gt__', '__hash__',
'__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__',
'__le__', '__len__',
'__lt__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__',
'__reversed__', '__rmul__', '__setattr__', '__setitem__',
'__sizeof__', '__str__',
'__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend',
'index', 'insert', 'pop',
'remove', 'reverse', 'sort']
>>>

Kokeillaan muutamia niistä:

>>> numbers = [1,2,3,4,5]
>>> numbers.reverse()
>>> numbers
[5, 4, 3, 2, 1]
>>> numbers.clear()
>>> numbers
[]

takaisin Pythonin yleiskäyttöön → pandas ja Python

Joskus helpoin vastaus löytyy hakemalla, esim. “pandas read csv” Googlessa.

Moduulien lataamisen esimerkki - csv sanakirjojen listana

# tuo moduuli
import csv

# Tiedoston lataaminen **with** sanalla. Tiedostot tietokoneelta Pythoniin.
with open('data/aineisto_ote.csv') as file:
    reader = csv.DictReader(file) # Tiedoston laittaminen reader-lukijaan ( biteistä sanoiksi ja kirjaimiksi)
    sanakirjojen_lista = list(reader) # Listan avaaminen muuttujaan

Taulukon luominen arvoista

import pandas as pd

df = pd.DataFrame(
  {
    "sarake1": [1, 2, 3, 4, 5],
    "sarake2": [1, 2, 3, 4, 5],
    "sarake3": [1, 2, 3, 4, 5]
  }
)

df

sarake1 sarake2 sarake3
0 1 1 1
1 2 2 2
2 3 3 3
3 4 4 4
4 5 5 5

Csv-tiedoston lukeminen kirjaston avulla: pd.read_csv

import pandas as pd

df = pd.read_csv("data/aineisto_ote.csv")

df

Tavoitteita tämän luennon jälkeen

  • Osaat käyttää Visual Studio Code tai JupyterLite -editoreita Tähän asti kaikki kurssin harjoitukset on suoritettu suoraan kurssisivujen upotetuissa editori-ikkunoissa. Päätteellä ohjelmointi sopii hyvin ohjelmoinnin aivan ensimmäisiin askeliin, mutta nyt on aika alkaa käyttää erillistä, erityisesti ohjelmointiin tarkoitettua editoria.
  • Osaat avata Github-repositoryn (kuten viikkotehtävässä) Chat-sovelluksessa chat-github.nuxt.dev

Datan tutkiminen I

Esimerkki: Kuluttajahintaindeksin kuukausiote

Csv-tiedoston lukeminen: read_csv

  
  
import pandas as pd  
df = pd.read_csv("data/kuluttajahintaindeksi_kk_ote_3lk.csv")  
df  
  
                        
Hyödyke Indeksipisteluku
0 01.1.1 Viljatuotteet ja leipä 109.66
1 01.1.2 Liha 115.87
2 01.1.3 Kala ja äyriäiset 146.70
3 01.1.4 Maitotuotteet, juusto ja kananmunat 109.71
4 01.1.5 Öljyt ja rasvat 120.50

98 rows × 2 columns

Tietotyypit: DataFrame, Series

  
  
type(df)  
  
                        

pandas.core.frame.DataFrame

Alku ja loppu: head, tail

  
  
df.head(3)  
  
                        
Hyödyke Indeksipisteluku
0 01.1.1 Viljatuotteet ja leipä 109.66
1 01.1.2 Liha 115.87
2 01.1.3 Kala ja äyriäiset 146.70
3 01.1.4 Maitotuotteet, juusto ja kananmunat 109.71
4 01.1.5 Öljyt ja rasvat 120.50
5 01.2.0 Elintarvikkeet 115.00
6 01.3.0 Juomat 118.00

98 rows × 2 columns

Tietotyypit: DataFrame, Series

  
  
type(df)  
  
                        
pandas.core.frame.DataFrame

Alku ja loppu: head, tail

  
  
df.head(3)  
  
                        
Hyödyke Indeksipisteluku
0 01.1.1 Viljatuotteet ja leipä 109.66
1 01.1.2 Liha 115.87
2 01.1.3 Kala ja äyriäiset 146.70

Pääpiirteet: info

  
  
df.info()  
  
                        

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 98 entries, 0 to 97Data columns (total 2 columns): #
Column Non-Null Count Dtype --- ------
-------------- ----- 0 Hyödyke 98 non-null object 1
Indeksipisteluku 98 non-null float64dtypes: float64(1), object(1)
memory usage: 1.7+ KB

Tilastoja: describe

  
  
df.describe()  
  
                        
Indeksipisteluku
count 98.000000
mean 110.002449
std 21.715095
min 43.190000
25% 100.582500
50% 109.300000
75% 115.532500
max 212.070000

Sarakkeen valinta

  
  
df["Hyödyke"]  
  
                        
0                         01.1.1 Viljatuotteet ja leipä  
1                                           01.1.2 Liha  
2                              01.1.3 Kala ja äyriäiset  
3            01.1.4 Maitotuotteet, juusto ja kananmunat  
4                                01.1.5 Öljyt ja rasvat  
...                        ...  
93               12.5.2 Asumiseen liittyvät vakuutukset  
94              12.5.3 Terveyteen liittyvät vakuutukset  
95           12.5.4 Liikenteeseen liittyvät vakuutukset  
96    12.6.2 Muut rahoituspalvelut, muualle luokittelemattomat  
97     12.7.0 Muut palvelut, muualle luokittelemattomat  
Name: Hyödyke, Length: 98, dtype: object

Järjestäminen: sort_values

  
  
df.sort_values("Indeksipisteluku")  
  
                        
Hyödyke Indeksipisteluku
63 08.2.0 Puhelin- ja faksilaitteet 43.19
65 09.1.1 Äänen ja kuvan vastaanottoon, tallennukseen, tallennusvälineet 56.72
32 04.6.3 Asuntolainojen korot 60.37
67 09.1.4 Tallennusvälineet 61.58
66 09.1.3 Tietojenkäsittelylaitteet 79.78

Aineiston rajaaminen

Voimme vertailla sarakkeen sisältöä:

  
  
df[df["Indeksipisteluku"] > 100]  
  
                        
Hyödyke Indeksipisteluku
0 01.1.1 Viljatuotteet ja leipä 109.66
1 01.1.2 Liha 115.87
2 01.1.3 Kala ja äyriäiset 146.70
3 01.1.4 Maitotuotteet, juusto ja kananmunat 109.71
4 01.1.5 Öljyt ja rasvat 120.50

75 rows × 2 columns

Toiminnot vaiheittain

  
  
df_yli_100 = df[df["Indeksipisteluku"] > 100]  
df_yli_100.sort_values("Indeksipisteluku", ascending=False)  
  
                        
Hyödyke Indeksipisteluku
28 04.5.3 Nestemäiset polttoaineet 212.07
14 02.2.0 Tupakka 164.12
55 07.2.2 Yksityisajoneuvojen polttoaineet ja voiteluaineet 159.23
27 04.5.1 Sähkö 153.27
9 01.2.1 Kahvi, tee ja kaakao 151.81

75 rows × 2 columns

Funktioiden ketjutus

  
  
df[df["Indeksipisteluku"] > 100].sort_values("Indeksipisteluku", ascending=False)  
  
                        
Hyödyke Indeksipisteluku
28 04.5.3 Nestemäiset polttoaineet 212.07
14 02.2.0 Tupakka 164.12
55 07.2.2 Yksityisajoneuvojen polttoaineet ja voiteluaineet 159.23
27 04.5.1 Sähkö 153.27
9 01.2.1 Kahvi, tee ja kaakao 151.81

75 rows × 2 columns

Esimerkki: Kuluttajahintaindeksin aikasarja

Csv:n lataaminen lisäargumentilla: parse_dates

  
import pandas as pd  
df = pd.read_csv("data/kuluttajahintaindeksi_muunnettu.csv", parse_dates=["Aika"])  
df
Aika Hyödyke Indeksipisteluku
0 2015-01-01 0 Kuluttajahintaindeksi 99.54
1 2015-01-01 01 ELINTARVIKKEET JA ALKOHOLITTOMAT JUOMAT 101.89
2 2015-01-01 01.1 Elintarvikkeet 101.86
3 2015-01-01 01.1.1 Viljatuotteet ja leipä 101.67
4 2015-01-01 01.1.1.1 Riisi 100.66
... ... ... ...
65699 2022-06-01 12.7.0.4.1 Kopiot dokumenteistä, lehti-ilmoitu... NaN
65700 2022-06-01 12.7.0.4.2 Muut maksut ja palvelut NaN

65700 rows × 3 columns

Pääpiirteet: info

df.info()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 65700 entries, 0 to 65699Data columns (total 3 columns): #   Column            Non-Null Count  Dtype  ---  ------            --------------  -----   0   Aika              65700 non-null  datetime64[ns] 1   Hyödyke           65700 non-null  object  2   Indeksipisteluku  61173 non-null  float64dtypes: datetime64[ns](1), float64(1), object(1)memory usage: 1.5+ MB

Tilastoja: describe

df.describe()
                        
Indeksipisteluku
count 61173.000000
mean 101.686028
std 11.260350
min 35.520000
25% 97.840000
50% 100.580000
75% 105.210000
max 251.290000

Esimerkki: Kotimaan lentoasemien matkustajamäärät ja rahtitonnit

Csv:n lataaminen lisäargumentilla: parse_dates

import pandas as pd  
df = pd.read_csv("data/lentoasemien_matkustajat_rahti_muunnettu.csv", parse_dates=["Aika"])  
df
                        
Aika Ilmoittava lentoasema Lennon tyyppi Saapuneet/lähteneet Yhteensä Matkustajamäärä Yhteensä Rahti ja posti yhteensä, tonnia Helsinki-Vantaa Matkustajamäärä Helsinki-Vantaa Rahti ja posti yhteensä, tonnia Muut kotimaan lentoasemat Matkustajamäärä Muut kotimaan lentoasemat Rahti ja posti yhteensä, tonnia Kansainvälinen Matkustajamäärä Kansainvälinen Rahti ja posti yhteensä, tonnia
0 2019-01-01 Yhteensä Yhteensä Saapuneet/lähteneet yhteensä 1969169 16265 276932 55 279130 177 1413107 16033
1 2019-01-01 Yhteensä Yhteensä Saapuneet 984340 7550 129975 41 147386 13 706979 7495
2 2019-01-01 Yhteensä Yhteensä Lähteneet 984829 8715 146957 13 131744 164 706128 8538
3 2019-01-01 Yhteensä Reittilento Saapuneet/lähteneet yhteensä 1857115 14743 276649 55 278772 177 1301694 14511
4 2019-01-01 Yhteensä Reittilento Saapuneet 931756 6733 129719 41 147185 13 654852 6678
... ... ... ... ... ... ... ... ... ... ... ... ...
7933 2022-06-01 Vaasa Reittilento Saapuneet 4843 0 4843 0 0 0 0 0
7934 2022-06-01 Vaasa Reittilento Lähteneet 4934 0 4934 0 0 0 0 0
7935 2022-06-01 Vaasa Tilauslento Saapuneet/lähteneet yhteensä 1674 0 0 0 0 0 1674 0
7936 2022-06-01 Vaasa Tilauslento Saapuneet 998 0 0 0 0 0 998 0
7937 2022-06-01 Vaasa Tilauslento Lähteneet 676 0 0 0 0 0 676 0

7938 rows × 12 columns

Pääpiirteet: info 2

df.describe(include='all')
                        
Aika Hyödyke Indeksipisteluku
count 65700 65700 61173
unique 65700 100 NaN
top 2019-01-01 Hyödyke A NaN
freq 1200 5000 NaN
mean NaN NaN 101.686
std NaN NaN 11.260
min NaN NaN 35.520
25% NaN NaN 97.840
50% NaN NaN 100.580
75% NaN NaN 105.210
max NaN NaN 251.290

Visualisointi

Miten valmistaudut grafiikoiden tekemiseen datasta: jos et käytä Jupyteriä tai JupyterLiteä
Asenna Matplotlib kehitysympäristöösi komennolla:

pip install matplotlib
        
import matplotlib.pyplot as plt  # matplotlib pitää tuoda, eli jatkossa pitäisi import:ta sekä pandas että matplotlib

Datan visualisoiminen on yksi toimittajan työprosessin vaihe. Usein siihen ei kannata käyttää paljon aikaa, mikäli olet kirjoittava toimittaja. Asioiden hiominen ja paranteleminen omaksi huvikseen alkaa viedä yllättävän paljon aikaa. Lisäksi matplotlib on ehkä kaikkein yksinkertaisin tapa esittää dataa kuvana - siitä ei saa vaan kaunista oikein millään, eikä sitä sen vuoksi kannata lähteä loputtomasti hiomaan.

Kaikkeen visualisoimiseen liittyvä kultainen sääntö on tällä luentosarjalla seuraava: lisää vain .plot() -komento minkä tahansa tarkastelemasi asian loppuun. Se toimii noin 75% ajasta.

Esimerkiksi luentokalvoilla on luotu väkilukujen summa eri mantereilla laskemalla väkimäärät yhteen. Tämä olisi visualisoitu grafiikka tuolta luennolta

df.groupby('continent').population.sum().plot(kind='barh')

Yllä oleva koodi antaa työkirjaan vaakasuoran pylväskaavion kunkin mantereen väestön summasta. Teknisesti ottaen se toimii, koska sum on sarja, matplotlib piirtää indeksin suhteessa arvoihin.

Jos sinulla on täysi Dataframe (normaali df eli taulu), sinun on yleensä annettava x ja y. Kuten näin:

df.plot(x="life_expectancy", y="per_capita_gdp", kind="scatter">

Tämä antaa kuvana hajontakaavion jokaisen maan elinajanodotteesta suhteessa sen henkeä kohti laskettuun BKT:hen.

Viivakaavio

Mikäli haluat käyttää huomattavasti enemmän aikaa ja luoda erilaisia visualisointeja grafiikkoja varten, niitä on alla vielä muutama esimerkki mahdollisista grafiikoista. Grafiikoita on luotu tämän viikon osion viimeisestä datasta, lentokenttädatasta.


asema = df["Ilmoittava lentoasema"] == "Savonlinna"  
saap_laht = df["Saapuneet/lähteneet"] == "Saapuneet/lähteneet yhteensä"  
(df[asema & saap_laht]  
    .loc[:, ["Aika", "Lennon tyyppi", "Yhteensä Matkustajamäärä"]]  
    .pivot(index='Aika', columns="Lennon tyyppi",   
           values="Yhteensä Matkustajamäärä")  
    .drop(columns="Yhteensä")  
    .plot(kind="line"))

<AxesSubplot:xlabel='Aika'>

Pinottu pylväskaavio


aika = df["Aika"] == "2022-06-01"
lentotyyppi = df["Lennon tyyppi"] == "Yhteensä"
saap_laht = df["Saapuneet/lähteneet"] == "Saapuneet/lähteneet yhteensä"
asema = -df["Ilmoittava lentoasema"].isin(["Yhteensä", "Helsinki-Vantaa"])

(df[aika & lentotyyppi & saap_laht & asema]
    .loc[:, [
        "Ilmoittava lentoasema", 
        "Helsinki-Vantaa Matkustajamäärä",
        "Muut kotimaan lentoasemat Matkustajamäärä",
        "Kansainvälinen Matkustajamäärä"]]
    .plot("Ilmoittava lentoasema", kind="bar", stacked=True))

Sekalaisia puuttuneita esimerkkejä

joita voit käyttää myöhemmin jos haluat virkistää muistiasi

Taulukon tallentaminen


Joskus tietoja halutaan tallentaa eteenpäin. Tässä tapauksessa ne pitää viedä levylle eli tallettaa csv:nä. Alla on kaksi esimerkkiä dataseteillä.

Scriptinä suoritettava työnkulku - esimerkkiscripti

Taulukon tallentaminen projektissa csv-tiedostoksi

Datan tutkiminen II

Aineistot

vanhojen osakeaseuntojen hinnat muunnettu data

yhteisöverot 2020 muunnettu data

business finland maksettu uudelleennimetty data


Tutustu uusiin käsitteisiin

Merge ja join – hyödylliset funktiot!

Pythonin join- ja merge-funktioiden esittelyt ja erot löydät lyhyesti Python in Plain English -linkistä.


Aggregointi Pythonissa usealla muuttujalla

Aggregointifunktion käytöstä on tutoriaali ulkoisessa linkissä verkossa täällä.

loc-valitsimen esittely tällä sivulla.



Näitä harjoitellaan viikkotehtävässä.

Esimerkki: Osakeasuntojen hinnat

df = pd.read_csv("data/vanhojen_osakeasuntojen_hinnat_muunnettu.csv", parse_dates=["Aika"])  
df
Aika Alue Talotyyppi Huoneluku Neliöhinta (EUR/m2) Kauppojen lukumäärä, varainsiirtoverotiedot vuoteen 2019 asti Kauppojen lukumäärä, varainsiirtoverotiedot vuodesta 2020 alkaen
0 2006-01-01 Koko maa Talotyypit yhteensä Yhteensä 1758.0 19075.0 NaN
1 2006-01-01 Koko maa Talotyypit yhteensä Yksiöt NaN NaN NaN
2 2006-01-01 Koko maa Talotyypit yhteensä Kaksiot NaN NaN NaN
3 2006-01-01 Koko maa Talotyypit yhteensä Kolmiot+ NaN NaN NaN
4 2006-01-01 Koko maa Rivitalot Yhteensä 1635.0 5621.0 NaN
... ... ... ... ... ... ... ...
66811 2021-10-01 Rovaniemi Rivitalot Kolmiot+ NaN NaN NaN

66816 rows × 7 columns

Pääpiirteet: info

df.info()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 66816 entries, 0 to 66815Data columns (total 7 columns): #   Column                                                            Non-Null Count  Dtype         ---  ------                                                            --------------  -----          0   Aika                                                              66816 non-null  datetime64[ns] 1   Alue                                                              66816 non-null  object         2   Talotyyppi                                                        66816 non-null  object         3   Huoneluku                                                         66816 non-null  object         4   Neliöhinta (EUR/m2)                                               30502 non-null  float64        5   Kauppojen lukumäärä, varainsiirtoverotiedot vuoteen 2019 asti     28559 non-null  float64        6   Kauppojen lukumäärä, varainsiirtoverotiedot vuodesta 2020 alkaen  4174 non-null   float64       dtypes: datetime64[ns](1), float64(3), object(3)memory usage: 3.6+ MB

Järjestäminen: sort_values

df.sort_values("Neliöhinta (EUR/m2)")
Aika Alue Talotyyppi Huoneluku Neliöhinta (EUR/m2) Kauppojen lukumäärä, varainsiirtoverotiedot vuoteen 2019 asti Kauppojen lukumäärä, varainsiirtoverotiedot vuodesta 2020 alkaen
65865 2021-10-01 Helsinki 1 Kerrostalot Yksiöt 9115.0 NaN 176.0
64821 2021-07-01 Helsinki 1 Kerrostalot Yksiöt 9057.0 NaN 185.0
63777 2021-04-01 Helsinki 1 Kerrostalot Yksiöt 9022.0 NaN 180.0
62733 2021-01-01 Helsinki 1 Kerrostalot Yksiöt 8959.0 NaN 174.0
60645 2020-07-01 Helsinki 1 Kerrostalot Yksiöt 8720.0 NaN 164.0
... ... ... ... ... ... ... ...

66816 rows × 7 columns

df.sort_values("Neliöhinta (EUR/m2)", ascending=False)
Aika Alue Talotyyppi Huoneluku Neliöhinta (EUR/m2) Kauppojen lukumäärä, varainsiirtoverotiedot vuoteen 2019 asti Kauppojen lukumäärä, varainsiirtoverotiedot vuodesta 2020 alkaen
65865 2021-10-01 Helsinki 1 Kerrostalot Yksiöt 9115.0 NaN 176.0
64821 2021-07-01 Helsinki 1 Kerrostalot Yksiöt 9057.0 NaN 185.0
63777 2021-04-01 Helsinki 1 Kerrostalot Yksiöt 9022.0 NaN 180.0
62733 2021-01-01 Helsinki 1 Kerrostalot Yksiöt 8959.0 NaN 174.0
60645 2020-07-01 Helsinki 1 Kerrostalot Yksiöt 8720.0 NaN 164.0
... ... ... ... ... ... ... ...

66816 rows × 7 columns

Tarkka rajaus


talorajaus = df['Talotyyppi'] == 'Kerrostalot'  
huonerajaus = df['Huoneluku'] == 'Yksiöt'  
aikarajaus = df['Aika'] >= '2020-01-01'  
df_rajattu = df[talorajaus & huonerajaus & aikarajaus].drop(columns='Kauppojen lukumäärä, varainsiirtoverotiedot vuoteen 2019 asti')
Aika Alue Talotyyppi Huoneluku Neliöhinta (EUR/m2) Kauppojen lukumäärä, varainsiirtoverotiedot vuodesta 2020 alkaen
58473 2020-01-01 Koko maa Kerrostalot Yksiöt 3488.0 2659.0
58485 2020-01-01 Pääkaupunkiseutu (PKS) Kerrostalot Yksiöt 6034.0 811.0
58497 2020-01-01 Koko maa ilman pääkaupunkiseutua Kerrostalot Yksiöt 2291.0 1847.0
58509 2020-01-01 Suuret kaupungit (yhteensä) Kerrostalot Yksiöt 5010.0 1446.0
58521 2020-01-01 Koko maa ilman suuria kaupunkeja Kerrostalot Yksiöt 1821.0 1212.0
... ... ... ... ... ... ...

696 rows × 6 columns

Puuttuvat missä tahansa sarakkeessa: any

df_rajattu[df_rajattu.isna().any(axis="columns")]
Aika Alue Talotyyppi Huoneluku Neliöhinta (EUR/m2) Kauppojen lukumäärä, varainsiirtoverotiedot vuodesta 2020 alkaen
58677 2020-01-01 Vantaa 2 Kerrostalot Yksiöt NaN 21.0
58713 2020-01-01 Porvoo Kerrostalot Yksiöt NaN 18.0
58725 2020-01-01 Hyvinkää Kerrostalot Yksiöt NaN 25.0
58737 2020-01-01 Järvenpää Kerrostalot Yksiöt NaN 14.0
58749 2020-01-01 Kerava Kerrostalot Yksiöt NaN 12.0
... ... ... ... ... ... ...

130 rows × 6 columns

Esimerkki: Yritystuet ja yhteisöverot

Excel-tiedoston lataaminen: read_excel

Asenna ensin tarvittava kirjasto kehitysympäristöösi:

pip install openpyxl

import pandas as pd  
df_bf = pd.read_excel("data/business_finland_maksetut_uudelleennimetty.xlsx")  
df_bf
Organisaation nimi Y-tunnus Maksuvuosi Avustus € Laina € EAKR-rahoitus € Tutkimusrahoitus € Yhteensä €
0 ! Aalto Avustajat Oy 2996949-9 2020 9536.00 0.0 0.0 0.0 9536.00
1 ! Aarre Avustajat Oy 2969310-3 2020 75688.00 0.0 0.0 0.0 75688.00
2 0.7 design Oy 2655941-9 2015 7716.00 0.0 0.0 0.0 7716.00
3 0.7 design Oy 2655941-9 2016 16461.00 0.0 0.0 0.0 16461.00
4 0.7 design Oy 2655941-9 2018 2349.00 0.0 0.0 0.0 2349.00
... ... ... ... ... ... ... ... ...
57120 Ömsesidiga Fastighets Ab Kimito Industritomten 2256921-4 2018 3000.00 0.0 0.0 0.0 3000.00

57125 rows × 8 columns

Pääpiirteet: info

df_bf.info()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 57125 entries, 0 to 57124Data columns (total 8 columns): #   Column              Non-Null Count  Dtype  ---  ------              --------------  -----   0   Organisaation nimi  57125 non-null  object  1   Y-tunnus            57125 non-null  object  2   Maksuvuosi          57125 non-null  int64   3   Avustus €           57125 non-null  float64 4   Laina €             57125 non-null  float64 5   EAKR-rahoitus €     57125 non-null  float64 6   Tutkimusrahoitus €  57125 non-null  float64 7   Yhteensä €          57125 non-null  float64dtypes: float64(5), int64(1), object(2)memory usage: 3.5+ MB

Yksittäiset arvot: value_counts

df_bf["Maksuvuosi"].value_counts()

2020 20779
2017 4985
2021 4625
2019 4590
2018 4508
2016 3066
2015 2681
2014 2559
2013 2432
2012 2379
2010 2261
2011 2260
Name: Maksuvuosi, dtype: int64

Csv-tiedoston lataaminen

df_verot = pd.read_csv("data/yhteisoverot_2020_muunnettu.csv")  
df_verot
Verovuosi | Skatteår Y-tunnus | FO-nummer Verovelvollisen nimi | Den skattskyldiges namn Verotuskunta | Beskattningskommun Verotettava tulo | Beskattningsbar inkomst Maksuunpannut verot yhteensä | Debiterade skatter Ennakot yhteensä | Förskott sammanlagt Veronpalautus | Skatteåterbäring Jäännösvero | Kvarskatt
0 2020 3134710-3 Justin Case Productions Oy 837 Tampere 0.00 0.00 0.00 0.0 0.00
1 2020 3083292-4 Suomen Ev. Lut. Kiinankielinen ry 091 Helsinki 0.00 0.00 0.00 0.0 0.00
2 2020 3125564-7 Pikk-Group Oy 300 Kuortane 0.00 0.00 0.00 0.0 0.00
3 2020 3123463-5 THPsykoterapia Oy 091 Helsinki 12849.01 2569.80 0.00 0.0 2569.80
4 2020 1029041-9 Kaiwur Oy 106 Hyvinkää 362057.42 73643.68 40664.99 0.0 32978.69
... ... ... ... ... ... ... ... ... ...
341731 2020 2972952-4 Lingon Games Oy 905 Vaasa 3144.56 628.91 628.91 0.0 0.00

341736 rows × 9 columns

Pääpiirteet: info

df_verot.info()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 341736 entries, 0 to 341735Data columns (total 9 columns): #   Column                                              Non-Null Count   Dtype  ---  ------                                              --------------   -----   0   Verovuosi | Skatteår                                341736 non-null  int64   1   Y-tunnus | FO-nummer                                341736 non-null  object  2   Verovelvollisen nimi | Den skattskyldiges namn      341736 non-null  object  3   Verotuskunta | Beskattningskommun                   341736 non-null  object  4   Verotettava tulo | Beskattningsbar inkomst          341736 non-null  float64 5   Maksuunpannut verot yhteensä | Debiterade skatter   341736 non-null  float64 6   Ennakot yhteensä | Förskott sammanlagt              341736 non-null  float64 7   Veronpalautus | Skatteåterbäring                    341736 non-null  float64 8   Jäännösvero | Kvarskatt                             341736 non-null  float64dtypes: float64(5), int64(1), object(3)memory usage: 23.5+ MB

Aineiston rajaaminen

df_verot = df_verot[df_verot["Verovuosi | Skatteår"] == 2020]  
df_bf = df_bf[df_bf["Maksuvuosi"] == 2020]

Nimeä uudelleen: rename


df_verot = df_verot.rename(columns={"Y-tunnus | FO-nummer": "Y-tunnus"})

Yhdistä: merge

df = pd.merge(df_verot, df_bf, on="Y-tunnus")  
df
Verovuosi | Skatteår Y-tunnus Verovelvollisen nimi | Den skattskyldiges namn Verotuskunta | Beskattningskommun Verotettava tulo | Beskattningsbar inkomst Maksuunpannut verot yhteensä | Debiterade skatter Ennakot yhteensä | Förskott sammanlagt Veronpalautus | Skatteåterbäring Jäännösvero | Kvarskatt Organisaation nimi Maksuvuosi Avustus € Laina € EAKR-rahoitus € Tutkimusrahoitus € Yhteensä €
0 2020 0868611-5 Fresh House Oy 049 Espoo 28694.74 5738.95 4999.92 0.00 739.03 Fresh House Oy 2020 10000.0 0.0 0.0 0.0 10000.0
1 2020 2016455-5 Connection House Oy 837 Tampere 0.00 0.00 0.00 0.00 0.00 Connection House Oy 2020 70000.0 0.0 0.0 0.0 70000.0
2 2020 0109579-3 Kalevala Koru Oy 091 Helsinki 0.00 0.00 0.00 0.00 0.00 Kalevala Koru Oy 2020 114980.0 0.0 0.0 0.0 114980.0
3 2020 2838009-2 JW Rakennusliike oy 091 Helsinki 14110.74 2822.15 3409.08 586.93 0.00 JW Rakennusliike oy 2020 10000.0 0.0 0.0 0.0 10000.0
4 2020 2078293-5 Ukemix järjestyksenvalvonta Oy 167 Joensuu 357089.46 72632.70 7976.04 0.00 64656.66 Ukemix järjestyksenvalvonta Oy 2020 80000.0 0.0 0.0 0.0 80000.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

20057 rows × 16 columns

Julkaiseminen

Monikäyttöiset visualisoinnit: Altair

Jos ajat komentoja IPython-tulkissa, asenna kirjasto ja muuta näyttöasetusta saadaksesi kaaviot näkymään selaimessasi:

pip install altair_viewer

import altair as alt
alt.renderers.enable('altair_viewer')
      

import pandas as pd
import altair as alt

df = pd.read_csv("data/kuluttajahintaindeksi_kk_ote_3lk.csv")
alt.Chart(df.nlargest(10, 'Indeksipisteluku')).mark_bar().encode(
  y=alt.Y('Hyödyke', sort="-x"),
  x='Indeksipisteluku'
)
020406080100120140160180200220Indeksipisteluku04.5.3 Nestemäiset polttoaineet02.2.0 Tupakka07.2.2 Yksityisajoneuvojen polttoaine…04.5.1 Sähkö01.2.1 Kahvi, tee ja kaakao08.1.0 Postipalvelut01.1.3 Kala ja äyriäiset11.2.0 Majoituspalvelut06.3.0 Sairaalapalvelut06.2.2 HammashoitoHyödyke

import pandas as pd
import altair as alt

df = pd.read_csv("data/kuluttajahintaindeksi_muunnettu.csv", parse_dates=["Aika"])

alt.Chart(df[df["Hyödyke"] == "01.1 Elintarvikkeet"]).mark_line().encode(
  x='Aika',
  y='Indeksipisteluku'
)

      
20152016201720182019202020212022Aika020406080100120Indeksipisteluku

  import pandas as pd
import altair as alt

df = pd.read_csv("data/kuluttajahintaindeksi_muunnettu.csv", parse_dates=["Aika"])

alt.Chart(df[df["Hyödyke"].str.startswith("01.1.1.4.")]).mark_line().encode(
  x='Aika',
  y='Indeksipisteluku',
  color='Hyödyke'
)
    
20152016201720182019202020212022Aika020406080100120Indeksipisteluku01.1.1.4.1 Kahvileivät01.1.1.4.2 Keksit ja korput01.1.1.4.3 Näkkileivät ja kuivat rie…01.1.1.4.4 Voileipä- ja suolakeksitHyödyke

Web-palvelut: Flask

Asenna aktivoidussa Python-kehitysympäristössä:


pip install Flask

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "<p>Hello, World!</p>"

if __name__ == '__main__':
    app.run(debug=True, use_reloader=True)

Templaatit

Luo HTML-tiedosto polkuun templates/index.html



{& for asia in asiat & }
  {{ asia }}
{& endfor & }


from flask import Flask
from flask import render_template

app = Flask(__name__)

@app.route("/")
def index():
    template = 'index.html'
    return render_template(template, asiat=[
        "Ensimmäinen asia", 
        "Toinen asia", 
        "Kolmas asia"
    ])

if __name__ == '__main__':
    app.run(debug=True, use_reloader=True)

Sisällön jäädyttäminen

pip install Frozen-Flask
from flask_frozen import Freezer
from app import app

freezer = Freezer(app)

if __name__ == '__main__':
    freezer.freeze()

Marimo ja vaihtoehtoiset Notebookit tulevaisuutta varten

Luennolla tutustuimme Hugging Face -taustapalveluissa (suoritus ilmaisena verkossa) Marimo -Notebook ohjelmistoon, joka mahdollistaa vuorovaikutteisen käyttöliittymän chatbottien luomiseen. Chatbotin avulla opiskelijat ja opettaja saivat esittää kysymyksiä ja tehdä analyyseja scikit-learnin Fish-datasetistä, joka sisältää tietoja kalalajeista ja niiden mittauksista. Datasetissä on yhteensä 159 riviä ja 7 saraketta, jotka käsittelevät kalojen lajeja, painoa, pituusmittauksia, korkeutta ja leveyttä. Chatbotin kautta ryhmäläiset pystyivät esittämään SQL-kyselyitä aineistolle, esimerkiksi selvittämään pisimmän hauen mittoja tai vertailemaan pienimmän ja suurimman hauen pituuseroja. Lisäksi kokeilimme erilaisten visualisointien, kuten Altairilla tehtyjen kaavioiden, luontia Marimo Chat UI:lla.

Marimon helppokäyttöisyys ja kyky tuottaa nopeasti visuaalisia ja helposti ymmärrettäviä tuloksia tekivät siitä erinomaisen työkalun datajournalismiin ja ohjelmointiharjoitteluun Jupyter Notebooksin ohella.

Marimo generative UI Chatbot -sivu

Myös valokuvien OCR-muuntamista varten tekstiksi oli demo Hugging Face-ympäristössä

Marimo Recipe bot