V OSA sisukord |
5.4 ANDMETÖÖTLUS MOODULIGA PANDAS
Sissejuhatus
Elame ajastul, kus kogutakse hulgaliselt erinevaid andmeid. Ühelt poolt sisaldab see näiteks ohte privaatsusele, teiselt poolt aga annab võimalusi õigemaid otsuseid teha. Otsustamiseks või ka lihtsalt millestki parema ülevaate saamiseks tuleb andmeid mõistlikult töödelda. Andmetöötluseks on väga erinevaid vahendeid, millest käesoleval kursusel kasutame Pythoni moodulit pandas. Selle nädala materjalides tutvustatakse pandast ja vaadeldakse andmeid teatrikülastuste kohta. Ülesanne on aga raamatukogude kohta. Andmed on saadud statistikaameti veebilehelt, kus on tohutult palju erinevaid andmeid. Valmis andmeid on võimalik saada ka mitmetest muudest kohtadest. Samuti on võimalik ise andmeid koguda, näiteks pulsikella abil. Natuke etteruttavalt võib öelda, et 7. ja 8. nädalal tehtav projekt võib põhineda andmetöötlusel. Seega on need materjalid ka projekti ettevalmistuseks.
Kuna pandase kasutamise kohta eriti palju eestikeelseid materjale pole ja pole ka väljakujunenud eestikeelset terminoloogiat, on materjalides kasutatud mõningaid otsemugandusi, nt seeria (Series
), andmefreim (DataFrame
). Andmetöötluse materjalid on seotud Inga Konovalova bakalaureusetööga. Tema hoiab silma peal ka vastaval foorumil ning kohendab soovituste põhjal materjale.
Installeerimine
Kursusel Programmeerimise alused II kasutavad paljud osalejad Pythonis programmide kirjutamiseks keskkonda Thonny. Vaatamegi, kuidas Thonnys installeerida Pythoni andmetöötluseks mõeldud moodul pandas.
Pandase paigaldamiseks tuleb Thonny ülamenüüst valida Tools
--> Manage packages
ja otsingusse kirjutada pandas ning vajutada nuppu Install
.
Kui te ei kasuta Thonnyt, siis võib pandase installeerimine olla mõnevõrra keerulisem. Windowsi käsurealt saab pandase installeerida käsuga py -m pip install pandas
Jupyter notebookis saab pandase installeerida reaga: !pip install pandas
. Lisainfot installeerimise kohta saab pandase veebilehelt.
Koos pandasega installitakse ka moodul NumPy. Tegelikult saaks pelgalt NumPy abiga andmeid töödelda, kuid pandases on rohkem funktsioone ning andmete töötlemine on mugavam. Mooduliga NumPy saab soovi korral tutvuda siin.
Graafikute tegemiseks läheb vaja moodulit Matplotlib, mille installeerimine on sama nagu pandase oma:
Thonnys paigaldamiseks tuleb ülamenüüst valida Tools
--> Manage packages
ja otsingusse kirjutada matplotlib ning vajutada nuppu Install
.
Windowsi käsurealt saab Matplotlib installeerida käsuga py -m pip install matplotlib
.
Jupyter notebookis tuleks kasutada koodirida: !pip install matplotlib
.
Andmestruktuurid
Pandase kohta leidub väga vähe eestikeelseid materjale ja terminoloogia on lünklik. Kasutame siin materjalides ingliskeelseid termineid ja nende toortõlkeid: seeria, andmefreim ja paneel.
Pandases on andmete hoidmiseks 3 põhilist andmestruktuuri:
Series
- seeriaDataFrame
- andmefreimPanel
- paneel
Enimkasutatav andmestruktuur on andmefreim ning ka nendes materjalides keskendutakse sellele. Esmalt aga tutvustatakse seeriaga.
Seeria (Series)
Seeria (Series
) on ühemõõtmeline, sarnastest andmetest koosnev, muutumatu suurusega andmestruktuur. Sellest võib mõelda ka kui kindla suurusega sõnastikust, milles igale võtmele vastab kindel väärtus.
Erinevus sõnastiku ja seeria vahel
Struktuuri poolest meenutab seeria kõige rohkem sõnastikku. Andmeid hoitakse siltidega seostatuna ja vajadusel võib kindla elemendi sildi järgi kätte saada. See meenutab sõnastiku võtme ja väärtuse süsteemi.
Sõnastiku puhul
isikud_sonastik = {'Võistleja nr 1': 'Mari', 'Võistleja nr 2': 'Joonas', 'Võistleja nr 3': 'Kati'} print(isikud_sonastik)
saame
{'Võistleja nr 1': 'Mari', 'Võistleja nr 2': 'Joonas', 'Võistleja nr 3': 'Kati'}
Seeria puhul
import pandas as pd isikud_seeria = pd.Series({'Võistleja nr 1': 'Mari', 'Võistleja nr 2': 'Joonas', 'Võistleja nr 3': 'Kati'}) print(isikud_seeria)
aga
Võistleja nr 1 Mari Võistleja nr 2 Joonas Võistleja nr 3 Kati dtype: object
Sõnastikku tasub kasutada juhul, kui on soov andmeid võtmete ja väärtuste paaridena hoida ning pole vajadust edaspidise põhjalikuma andmete töötluse järele. Andmetöötluse jaoks sobib paremini seeria, sest sellel on rohkem funktsioone (aritmeetilised tehted, sorteerimine, filtreerimine jne). Tegevused toimuvad ka efektiivsemalt ning kood on lihtsam.
Näitena vaadeldakse seeriat, milles hoitakse õpilaste arvusid klasside kaupa.
import pandas as pd import matplotlib.pyplot as plot klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], index = ['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], name = 'Õpilaste arv klassis') print(klassid)
Seeria puhul loetakse veeruks vaid andmete veergu ja seal asuvaid andmeid töödeldakse. Siltide veerg on vajalik konkreetsetele andmetele viitamiseks.
Illustreerime ülaltoodud andmeid graafikul.
klassid.plot.bar(title = 'Õpilaste arvud klasside kaupa') plot.show()
Täpsemalt saab graafikute loomise ja kujundamise kohta infot materjalide lõpuosas esitatud näitest ja näiteks ingliskeelsest materjalist.
Sarnasus järjendi ja seeria vahel
Seeria on teatud mõttes sarnane tavalise järjendiga. Järgmises näites on püütud järjendile eriti sarnane seeria tekitada.
import pandas as pd järjend = ['a', 'b', 'c', 'd'] print(järjend) print('Element indeksiga 0 järjendis on:', järjend[0])
Ekraanile ilmub siis
['a', 'b', 'c', 'd'] Element indeksiga 0 järjendis on: a
Anname ka seerias samad indeksid
seeria = pd.Series(['a', 'b', 'c', 'd'], index = [0, 1, 2, 3]) print(seeria) print('Element sildiga 0 seerias on:', seeria[0])
Nüüd saame ekraanile
0 a 1 b 2 c 3 d dtype: object Element sildiga 0 seerias on: a
Nii seeria kui järjendi puhul on konkreetsele elemendile lisatud viide, mille järgi saab vajadusel elemendi kätte. Järjendis on elementidel järjekorranumbrid ehk indeksid 0, 1, 2, ..., n
. Seeria puhul on lisaks indeksitele tegemist siltidega (ingl label), mille kasutaja saab ise määrata. Sildid ei pruugi olla alati järjestikused ja isegi mitte arvud. Klasside õpilaste arvu näites polnud näiteks arvud.
Uue seeria loomine
Uue Series-tüüpi andmestruktuuri saab luua järgmiselt.
pandas.Series(data, index, dtype, copy)
Kõiki parameetreid ei pea defineerimisel kasutama, mingi parameetri ärajätmisel kasutatakse selle vaikimisi määratud väärtust. Kui näiteks ära jätta data
, kuid lisada siltide järjend, siis genereeritakse seeria, mille igale sildile vastab spetsiaalne väärtus NaN
(Not a Number).
Järgmine tabel kirjeldab, mis tüüpi väärtused igale parameetrile saab anda ja mida need tähendavad.
Parameeter | Selgitus |
---|---|
data | Andmed võivad olla järjendi, sõnastiku või konstandi (üks element) kujul. Näiteks pandas.Series({'Mari': '12', 'Karmo': '15', 'Malle': '20'}, …) või pandas.Series(['punane', 'kollane', 'sinine'], …) või pandas.Series('a', ...) |
index | Siltide järjend. Vaikimisi määratakse siltideks arvud 0, 1, 2,..., n-1, kus n on elementide arv parameetriga data lisatud andmestruktuuris. |
dtype | Andmete tüüp, mida seerias hoitakse. Vaikimisi tuvastatakse tüüp antud andmetest. Näiteks kui hoitakse seerias ujukomaarve, siis vaikimisi määratakse tüübiks float . |
copy | Määrab, kas andmetest, mida kasutatakse, tehakse koopia. Vaikimisi väärtus false . |
Lisaks tabelis olevatele parameetritele, võib kasulikuks osutuda ka name
, mille lisamisel saab seeriale määrata nime.
Vaatame ülaltoodud klasside ja õpilaste näidet uuesti ning analüüsime selle seeria loomist:
klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], #andmed ehk data index = ['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], #sildid name = 'Õpilaste arv klassis') #seeriale antud nimi
Siltide arv (antud juhul klasside arv) peab olema võrdne parameetriga data
antud andmestruktuuri elementide arvuga ehk õpilaste arvude arvuga. Antud juhul on meil tegemist 19 erineva klassiga ning järelikult ka õpilaste arvusid peab olema andmete järjendis 19. Parameetri name
abil on seeriale lisatud nimeks “Õpilaste arv klassis”. Muudele parameetritele määrati väärtused vaikimisi.
Loodud seeria näeb ekraanile väljastatuna välja niisugune.
1a 24 1b 23 2 21 3a 22 3b 28 4a 26 4b 30 5 28 6a 31 6b 35 7 33 8 32 9 29 10 reaal 27 10 sotsiaal 25 11 reaal 30 11 sotsiaal 26 12 reaal 31 12 sotsiaal 22 Name: Õpilaste arv klassis, dtype: int64
Andmete tüübiks on vaikimisi määratud int64
, sest õpilaste arvude näol on tegemist täisarvudega.
Erandjuhuna saab seeria luua nii, et loomisel on lisatud vaid üks väärtus ja näiteks 4 silti. Sel juhul korratakse seda ühte väärtust 4 korda ning luuakse 4 sama väärtusega elementi.
import pandas as pd seeria = pd.Series(7, index = [0, 2, 4, 6]) print(seeria)
Ekraanile saame
0 7 2 7 4 7 6 7 dtype: int64
Sildid võivad olla arvud, sõned või mingit muud mittemuteeritavat tüüpi.
seeria = pd.Series([7, 'Tartu Ülikool', 3.14, -1789710578, 'Informaatika!'], index = ['A', '2', 'C', '4', 'E']) print(seeria)
Väljund
A 7 2 Tartu Ülikool C 3.14 4 -1789710578 E Informaatika! dtype: object
Ülaltoodud näidetes loodi seeriad kasutades järjendit või konstanti (ühte elementi). Lisatavad andmed võivad olla ka sõnastikus.
import pandas as pd dict_isikud = {'Võistleja nr 1' : 'Mari','Võistleja nr 2': 'Joonas','Võistleja nr 3': 'Kati'} seeria = pd.Series(dict_isikud) print(seeria)
Väljund
Võistleja nr 1 Mari Võistleja nr 2 Joonas Võistleja nr 3 Kati dtype: object
Selleks, et tutvuda osaga võimalustest, mida seeria kasutamine andmete töötlemiseks annab, võtame ette juba tuttava klasside õpilaste arvude näite.
import pandas as pd klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], index = ['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], name = 'Õpilaste arv klassis') print(klassid)
1a 24 1b 23 2 21 3a 22 3b 28 4a 26 4b 30 5 28 6a 31 6b 35 7 33 8 32 9 29 10 reaal 27 10 sotsiaal 25 11 reaal 30 11 sotsiaal 26 12 reaal 31 12 sotsiaal 22 Name: Õpilaste arv klassis, dtype: int64
Oletame, et meil on vaja eraldada ainult algklasside õpilaste arvud. Seda saab teha kahel moel, kasutades andmete asukohta seerias või silte. Asukoha järgi saab andmeid eraldada seetõttu, et lisaks siltidele, on igal elemendil olemas ka indeks, mis tähistab numbriliselt elemendi asukohta seerias. Nagu ka järjendis, on indeksiteks arvud 0, 1, 2, ..., n-1
, kus n tähistab elementide arvu seerias.
import pandas as pd klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], index = ['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], name = 'Õpilaste arv klassis') algklassid = klassid[['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b']] print(algklassid)
Ja teistmoodi
import pandas as pd klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], index = ['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], name = 'Õpilaste arv klassis') algklassid = klassid[0:10] print(algklassid)
Tulemus tuleb mõlemal juhul täpselt sama.
1a 24 1b 23 2 21 3a 22 3b 28 4a 26 4b 30 5 28 6a 31 6b 35 Name: Õpilaste arv klassis, dtype: int64
Järgmisena vaatame, mitu klassi kokku on meil seerias, selleks kasutame .size
tunnust.
import pandas as pd klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], index = ['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], name = 'Õpilaste arv klassis') print(klassid.size)
Väljastatakse 19
.
Tihti on vaja andmeid mingis kindlas järjekorras sorteerida, sorteerime klassid õpilaste arvude järgi kahanevas järjekorras funktsiooni .sort_values()
abil. Samuti saab sorteerida ka siltide järgi funktsiooni .sort_index()
abil.
import pandas as pd klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], index = ['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], name = 'Õpilaste arv klassis') klassid_kahanevalt = klassid.sort_values(ascending=False) print(klassid_kahanevalt)
6b 35 7 33 8 32 12 reaal 31 6a 31 11 reaal 30 4b 30 9 29 3b 28 5 28 10 reaal 27 11 sotsiaal 26 4a 26 10 sotsiaal 25 1a 24 1b 23 3a 22 12 sotsiaal 22 2 21 Name: Õpilaste arv klassis, dtype: int64
Mõnikord on vaja lisada seeriasse andmeid juurde. Vaatame, kuidas saab kahe seeria andmed ühendada. Lisame juurde õpetajate arvu, õpilaste arvu kokku ja klasside arvu kokku. Selleks loome uue Series
-tüüpi andmestruktuuri, mille andmeteks on järjend õpetajate arvuga, õpilaste arvuga kokku ja klasside arvuga kokku ning mille siltideks on ‘Õpetajate arv’, ‘Õpilaste arv kokku’ ja ‘Klasside arv kokku’. Õpilaste arvu kokku saame kasutades .sum()
funktsiooni klasside seeria peal ning klasside arvu kokku leiame atribuudiga .size
, mida kasutasime ka varem.
import pandas as pd klassid = pd.Series([24, 23, 21, 22, 28, 26, 30, 28, 31, 35, 33, 32, 29, 27, 25, 30, 26, 31, 22], index=['1a', '1b', '2', '3a', '3b', '4a', '4b', '5', '6a', '6b', '7', '8', '9', '10 reaal', '10 sotsiaal', '11 reaal', '11 sotsiaal', '12 reaal', '12 sotsiaal'], name='Õpilaste arv klassis') uus_seeria = pd.Series([25, klassid.sum(), klassid.size], index=['Õpetajate arv', 'Õpilaste arv kokku','Klasside arv kokku']) klassid = pd.concat([klassid, uus_seeria]) print(klassid)
Tulemuseks on uuendatud klasside seeria. Oluline on meelde jätta, et funktsioonide rakendamisel seeria peal, tuleb uus ja modifitseeritud muutuja alati uuesti omistada, kas siis uuele muutujale või kirjutada vana seeria üle.
1a 24 1b 23 2 21 3a 22 3b 28 4a 26 4b 30 5 28 6a 31 6b 35 7 33 8 32 9 29 10 reaal 27 10 sotsiaal 25 11 reaal 30 11 sotsiaal 26 12 reaal 31 12 sotsiaal 22 Õpetajate arv 25 Õpilaste arv kokku 523 Klasside arv kokku 19 dtype: int64
Andmefreim (DataFrame
)
Juba seeria abil saab andmeid teatud määral töödelda ja illustreerida. Veelgi põnevamaid võimalusi pakub andmefreim (DataFrame
), mis kujutab endast põhimõtteliselt tabelit. Seeria tähistab andmefreimis (DataFrame
) ühte veergu. Andmefreimis võivad olla erinevat tüüpi andmed ja selle suurust saab muuta. Ridadele ja veergudele saab rakendada aritmeetilisi funktsioone - näiteks saab veergusid liita, lahutada, korrutada ja jagada ning arvutada rea või veeru kaupa selle maksimumi, keskmist jpm.
Esimese näitena vaatame andmefreimi, milles on õpilaste nimed ning eesti keele ja matemaatika hinded.
import pandas as pd import matplotlib.pyplot as plot opilased = { 'matemaatika': pd.Series([5, 4, 5], index = ['Mirjam', 'Sirje', 'Vaido']), 'eesti keel': pd.Series([5, 5, 5, 4], index = ['Mirjam', 'Sirje', 'Vaido', 'Kunnar'])} opilased_tabel = pd.DataFrame(opilased) print(opilased_tabel)
Andmefreimis ei loeta siltide veergu ja veergude pealkirjasid ridade ja veergude hulka. Erinevalt seeriast, vastab siin igale sildile üks rida. See koosneb põhimõtteliselt pealkirjaga seeriatest (veergudest), millel on ühised sildid.
Illustreerime ülaltoodud andmeid graafikul:
opilased_tabel.plot.bar() plot.show()
Andmefreimi saab luua järgmiselt:
pandas.DataFrame(data, index, columns, dtype, copy)
Ka andmefreimi puhul ei pea kõiki parameetreid defineerimisel kasutama, parameetri ärajätmisel kasutatakse selle vaikimisi määratud väärtust.
Parameeter | Selgitus |
---|---|
data | Andmed võivad olla n-dimensioonilise andmemassiivi, sõnastiku, konstandi, järjendi või teise andmefreimi kujul. Näiteks: pandas.DataFrame( |
index | Ridade siltide järjend, pikkus peab olema võrdne ridade arvuga. Vaikimisi määratakse arvud 0, 1, 2, ..., n-1, kus n on ridade arv. |
columns | Veergude siltide järjend, pikkus peab olema võrdne veergude arvuga. Vaikimisi määratakse arvud 0, 1, 2, ..., m-1, kus m on veergude arv. |
dtype | Andmetüüp, mida DataFrames olevatele andmetele määratakse. Vaikimisi järeldatakse andmetest. |
copy | Määrab, kas andmetest, mida kasutatakse, tehakse koopia. Vaikimisi väärtus False . |
Vaatame ülaltoodud klasside ja õpilaste näidet uuesti ning analüüsime selle seeria loomist:
import pandas as pd opilased = { 'matemaatika': pd.Series([5, 4, 5], index = ['Mirjam', 'Sirje', 'Vaido']), 'eesti keel': pd.Series([5, 5, 5, 4], index = ['Mirjam', 'Sirje', 'Vaido', 'Kunnar'])} opilased_tabel = pd.DataFrame(opilased) print(opilased_tabel)
Sisendiks antakse sõnastik, mille võtmed on veeru pealkirjad ja vastavateks väärtusteks kaks seeriat (kaks veergu). Seeriate siltideks on õpilaste nimed ning andmeteks õpilaste poolt saadud hinded. Pange tähele, et mõlemas seerias on õpilaste arv võrdne hinnete arvuga, kuid lisatavad seeriad pole sama pikad. Muudele parameetritele määrati väärtused vaikimisi.
Rohkem näiteid andmefreimide loomisest:
Tühja andmefreimi loomine:
import pandas as pd tühi = pd.DataFrame() print(tühi)
Väljund:
Empty DataFrame Columns: [] Index: []
Andmefreimi loomine järjendi põhjal:
Tegemist on järjendite järjendiga, mis antakse ette andmefreimi andmetena. Columns
parameetriks antud järjend määrab ära veergude pealkirjad. Andmed jaotatakse veergudesse vastavalt nende paigutusele järjendites, iga järjend on eraldi rida ja sisemiste järjendite elemendid asuvad erinevates veergudes.
import pandas as pd isikud = [['Juss',10],['Illar',12],['Mari-Liis',13]] andmestruktuur = pd.DataFrame(isikud, columns = ['Nimi','Vanus']) print(andmestruktuur)
Nimi Vanus 0 Juss 10 1 Illar 12 2 Mari-Liis 13
Andmefreimi loomine sõnastiku põhjal:
Sarnaselt ülaltoodud näitele on siingi sõnastiku võtmed veergude pealkirjadeks. Konkreetsetele võtmetele vastavad järjendid on aga veergudes väärtusteks. Andmefreimi loomisel on etteantud ka siltide järjend.
import pandas as pd voistlejad = {'Nimi' : ['Malle', 'Kalle', 'Jaanus', 'Pille'], 'Vanus' : [24, 34, 51, 47]} voistlejad_tabel = pd.DataFrame(voistlejad, index = ['Nr. 1', 'Nr. 2', 'Nr. 3', 'Nr. 4']) print(voistlejad_tabel)
Väljund:
Nimi Vanus Nr. 1 Malle 24 Nr. 2 Kalle 34 Nr. 3 Jaanus 51 Nr. 4 Pille 47
Andmefreimi (DataFrame
) loomine sõnastikust, milles on seeriad:
Ülaltoodud näide õpilastest ja hinnetest sobib hästi näiteks, kus andmefreim luuakse sõnastikust, milles on seeriad.
import pandas as pd opilased = { 'matemaatika' : pd.Series([5, 4, 5], index=['Mirjam', 'Sirje', 'Vaido']), 'eesti keel' : pd.Series([5, 5, 5, 4], index = ['Mirjam', 'Sirje', 'Vaido', 'Kunnar'])} opilased_tabel = pd.DataFrame(opilased) print(opilased_tabel)
Väljund:
eesti keel matemaatika Kunnar 4 NaN Mirjam 5 5.0 Sirje 5 4.0 Vaido 5 5.0
Matemaatika veerus oli andmeid vaid 3 inimese kohta, seega lisati Kunnari matemaatika hindeks NaN
ehk siis “pole arv” väärtus (ingl not a number). Sellest tulenevalt muudeti selle veeru väärtused ujukomaarvudeks (ingl float), sest NaN
väärtust loetakse ujukomaarvuks.
Edasi tutvume mõnede andmefreimi võimalustega ja selleks on jällegi hea kasutada õpilaste ja hinnete näidet. Oletame, et pandi välja veel mitme aine hinded ning vaja oleks lisada ka need tabelisse.
Selleks loome sama põhimõtte järgi uue andmefreimi ning ühendame .join()
funktsiooni abil kaks andmefreimi omavahel.
import pandas as pd lisa = { 'inglise keel' : pd.Series([5, 4, 5, 5, 3], index = ['Mirjam', 'Sirje', 'Vaido','Karmen','Kunnar']), 'kehaline kasvatus' : pd.Series([5, 5, 5, 4, 5], index = ['Mirjam', 'Sirje', 'Vaido', 'Karmen', 'Kunnar'])} lisa_tabel = pd.DataFrame(lisa)
Uute andmetega tabeli kuju:
inglise keel kehaline kasvatus Mirjam 5 5 Sirje 4 5 Vaido 5 5 Karmen 5 4 Kunnar 3 5
Algse tabeli kuju:
eesti keel matemaatika Kunnar 4 NaN Mirjam 5 5.0 Sirje 5 4.0 Vaido 5 5.0
Näeme, et lisatavas tabelis on rohkem õpilasi, seega peame ühendama algse õpilaste tabeli uue tabeliga, et kõik nimed oleksid olemas ka uues tabelis.
import pandas as pd opilased = { 'matemaatika': pd.Series([5, 4, 5], index = ['Mirjam', 'Sirje', 'Vaido']), 'eesti keel': pd.Series([5, 5, 5, 4], index = ['Mirjam', 'Sirje', 'Vaido', 'Kunnar'])} opilased_tabel = pd.DataFrame(opilased) lisa = { 'inglise keel' : pd.Series([5, 4, 5, 5, 3], index = ['Mirjam', 'Sirje', 'Vaido','Karmen','Kunnar']), 'kehaline kasvatus' : pd.Series([5, 5, 5, 4, 5], index = ['Mirjam', 'Sirje', 'Vaido', 'Karmen', 'Kunnar'])} lisa_tabel = pd.DataFrame(lisa) uus_tabel = lisa_tabel.join(opilased_tabel) print(uus_tabel)
Uue tabeli kuju:
inglise keel kehaline kasvatus eesti keel matemaatika Mirjam 5 5 5.0 5.0 Sirje 4 5 5.0 4.0 Vaido 5 5 5.0 5.0 Karmen 5 4 NaN NaN Kunnar 3 5 4.0 NaN
Lähenemas on õppeaasta lõpp ja lisanduvad ka viimased üksikud hinded, mis tuleb tabelisse lisada. Lisame hinded ühekaupa õigele kohale. Esimese parameetriga määrame õpilase nime (sildi), kelle hinnet soovime muuta ning teise parameetriga aine (veeru):
uus_tabel.loc['Karmen','matemaatika'] = 3 uus_tabel.loc['Karmen', 'eesti keel'] = 5 uus_tabel.loc['Kunnar', 'matemaatika'] = 3
Kuna keskmisest hindest oleneb ekskursioonile minek, soovime välja arvutada keskmised hinded ja lisada need uude veergu “Keskmine hinne”. Lisame uue veeru ja arvutame õpilaste keskmised hinded. Õige rea valimiseks kasutame tunnust .loc
ning keskmise arvutamiseks reas funktsiooni .mean()
:
uus_tabel['Keskmine hinne'] = pd.Series([uus_tabel.loc['Sirje'].mean(), uus_tabel.loc['Mirjam'].mean(), uus_tabel.loc['Vaido'].mean(), uus_tabel.loc['Karmen'].mean(), uus_tabel.loc['Kunnar'].mean()], index = ['Sirje', 'Mirjam', 'Vaido', 'Karmen', 'Kunnar'])
Pane tähele, et uude veergu lisatavad keskmised peavad olema siltide järjendis olevate siltidega samas järjekorras, siis saab õige hinne lisatud õige õpilase juurde.
Tabel, milles on puuduvad hinded ja keskmised:
inglise keel kehaline kasvatus eesti keel matemaatika \ Mirjam 5 5 5.0 5.0 Sirje 4 5 5.0 4.0 Vaido 5 5 5.0 5.0 Karmen 5 4 5.0 3.0 Kunnar 3 5 4.0 3.0 Keskmine hinne Mirjam 5.00 Sirje 4.50 Vaido 5.00 Karmen 4.25 Kunnar 3.75
Järgmises peatükis leiate veelgi näiteid andmetöötluse jaoks kasutatavatest andmefreimi funktsioonidest.
V OSA sisukord |