15 Pandas¶
Pandas er pakki fyrir gagnameðhöndlun og gagnagreiningu í Python. Með Pandas er auðvelt að lesa stórar gagnaskrár, bæði textaskrár og töflureikniskrár (t.d. úr Excel eða Google sheets) og flokka gögnin á ýmsa vegu, velja hlutgögn (línur eða dálka), gera ýmsa útreikninga, og skrifa niðurstöðuna, annaðhvort í venjulegt úttak (í vinnubók/á skjá) eða í nýja skrá. Það er líka hægt að búa til NumPy-fylki úr Pandas-töflum og nota Matplotlib til að birta niðurstöður grafískt. Dæmigerðar Pandas-aðgerðir eru oft framkvæmdar í töflureikni, en það hefur ýmsa kosti að gera þær í forriti, t.d. ef maður vill framkvæma samsskonar reikninga aftur og til þess er Pandas pakkinn tilvalinn.
Á netinu má finna 10 mín. leiðbeiningar, svindlblað og annað slíkt. Það síðara er e.t.v. heldur vandaðra.
15.1 Pandas gögn¶
Pandas-pakkinn er skv. hefð fluttur inn með
import pandas as pd
Aðalgagnatögin í Pandas eru pd.Series (runa] sem er einvíð runa gagna, og pd.DataFrame (gagnatafla) sem er tvívíð tafla. Tvennt greinir Pandas frá NumPy: Í fyrsta lagi hafa stökin í rununum og línur og dálkar taflanna auðkenni eða nöfn, og í öðru lagi geta dálkar taflanna verið af mismunandi tagi, einn dálkur gæti t.d. geymt strengi, annar heiltölur og sá þriðji kommutölur.
Venjulega er vísað í einstaka dálka og línur eftir nöfnum þeirra, en það er líka hægt að vísa í þær eftir númeri (sem sé hvar þær eru í röðinni). Sama gildir um hluttöflur. Tafla 15.2 sýnir skipanir fyrir báðar aðferðirnar.
Athugasemd
Í opinberri Pandas-hjálp eru auðkenni eða nöfn á línum og dálkum kölluð labels, og línurnar stundum kallaðar index.
Sýnidæmi
Á vef hagstofunnar er hægt að hlaða niður allskonar talnaefni, m.a. kosningaúrslitum. Skráin cs.hi.is/python/kosningar.xlsx sem er fengin þaðan geymir úrslit alþingiskosninga 2017. Skráin hefur fjóra dálka: stafur, flokkur, atkvæði og þingsæti (stafur er listabókstafur). Smellið gjarna á þessa skrá og skoðið hana í Excel.
Hér er svo forritsbútur sem les skrána, og birtir hana, reiknar heildarfjölda atkvæða, bætir við dálki með hlutfalli atkvæðanna sem hver flokkur fékk, og birtir loks þessa auknu töflu:
import pandas as pd
kosn = pd.read_excel("http://cs.hi.is/python/kosningar.xlsx")
display(kosn)
n = sum(kosn["Atkvæði"])
kosn["Hlutf"] = kosn["Atkvæði"]/n
display(kosn)
Breytan kosn er gagnatafla af taginu pd.DataFrame
. Hér fylgir byrjunin á
töflunni sem birtist:
Æfing
Afritið Sýnidæmið yfir í vinnubók og keyrið það. Prófið að nota print í stað display. Bætið svo við samtals-línu með:
kosn.loc["Samtals"] = kosn.sum()
kosn.loc["Samtals", "Stafur"] = ""
kosn.loc["Samtals", "Flokkur"] = ""
(seinni tvær línurnar eru tilkomnar vegna þess að það á ekki að leggja saman stafina og listana). Bætið líka við dálki „Atkv-sætis“ með atkvæði á bak við hvert þingsæti með því að deila í atkvæðin með þingsætunum. Loks er hægt að birta hlutfallið sem prósentu og einum aukastaf, og aftasta dálkinn án aukastafa með skipununum:
birt = kosn.style.format({"Hlutf": "{:.1%}", "Atkv-sætis": "{:.0f}"})
display(birt)
(í innri slaufusvigunum eru snið líkt og í f-strengjum).
Í sýnidæminu og æfingunni sést að sjálfgefin auðkenni línanna eru einfaldlega
tölurnar 0–10, en dálkarnir fá nöfn úr hauslínu Excel-skrárinnar. Með
display
prentast taflan út HTML-sniðin, en með print
fæst hún með
textasniði.
Við sjáum líka að vísað er í dálk töflu eins og í gildi í uppflettitöflu
(dictionary), með vísi sem er nafn dálksins innan hornklofa, en með því að
nota .loc er í staðinn vísað í línu, og þá er líka hægt að vísa í einstakt
stak eða reit í töflunni eins og í NumPy fylki með
gagnatafla.loc[lína,dálkur]
. Tökum líka eftir að reikniaðgerð (hér deiling)
verkar á öll stök dálks í einu, eins og í NumPy.
15.2 Smíði gagnatafla¶
Í stað þess að lesa gagnatöflur úr skrám eins og gert er í kaflanum hér á undan
er hægt að búa þær til úr breytum sem þegar eru fyrir hendi, hvort sem er
uppflettitöflum, listum eða NumPy-fylkjum. Til þess er hægt að nota
gagnatöflusmiðinn (-constructor) pd.DataFrame
. Einfallt kall á hann er:
df = pd.DataFrame(data)
þar sem data
getur verið NumPy-fylki, listi af listum eða
uppflettitafla. Í tveimur fyrri tilvikunum fá dálkarnir nöfn 0, 1, 2,… en
með uppflettitöflu gefa lyklar hennar nöfn dálkanna. Þegar data
er listi af
listum verður hver innri listi lína í gagnatöflunni, en ef það er uppflettitafla
með gildi sem eru listar lenda þeir í dálkum gagnatöflunnar. Svo er hægt að bæta
viðbótarstikum við kallið á DataFrame
, t.d. columns=["D1", "D2"]
til að
gefa dálkunum nöfn og index=[1,2,3]
til að gefa línunum nöfn (auðkenni).
Þegar gagnatafla er búin til úr NumPy-fylki með df = pd.DataFrame(A)
er
fylkið ekki afritað heldur geymir taflan tilvísun í fylkið, sbr. athugasemd í
kafla 10.5.2. Til að taka í staðinn afrit má
nota kallið
df = pd.DataFrame(A, copy=True)
Sýnidæmi:
Skipanirnar:
T = {"nafn": ["Ari", "Ása"], "aldur":[12,18]}
rng = np.random.default_rng(seed=42)
A = rng.random(size=(2,3))
df = pd.DataFrame(T)
slembi = pd.DataFrame(A, columns=["A", "B", "C"])
print(df)
print(slembi)
prenta út:
nafn aldur
0 Ari 12
1 Ása 18
A B C
0 0.773956 0.438878 0.858598
1 0.697368 0.094177 0.975622
15.3 Helstu Pandas-skipanir¶
Hér fylgja töflur yfir nokkrar helstu Pandas-skipanirnar. Þær eru hvergi nærri
tæmandi, en í staðinn vísast í svindlblöðin sem nefnd eru hér fremst í
innganginum. Í töflunum stendur df.
fyrir gagnatöflu
(DataFrame) og s.
fyrir runu (Series), sem sé stakan dálk eða línu.
|
Býr til {„col1“:[1,2,3], col2 |
|
Vísað í dálk |
|
Dálkur númer 2 (runa) |
|
Lína með auðkenni 3 (runa) |
|
Lína með auðkenni |
|
Lína númer 3 (runa) |
|
Línur auðkenndar 2, 4 og 5 (hluttafla) |
|
Línur númer 3, 4 og 5 (hluttafla) |
|
Dálkar A, B og D (hluttafla) |
|
Línur auðkenndar 3, 4 og 5, dálkar frá A t.o.m. C |
|
Vísað í tiltekinn reit |
|
Velja línur þar sem dálkur |
|
Lesa fremsta vinnublað (sheet) inn í df |
|
Lesa vinnublað s inn í df (s má vera nafn eða nr.) |
|
Lesa alla dálka sem strengi |
|
Skrifa í Excelskrá |
|
Lesa töflu |
|
Dálkar aðskildir með |
|
Lesa kommuaðskilda skrá (þmt 1. línu), |
|
Lesa kommuaðskilda skrá, línuauðkenni úr dálki 2 |
|
Lesa skrá með bilum á milli dálka |
|
Lesa skrá með fastri dálkabreidd. Breidd dálka er |
|
Bætt við nýjum dálki sem er tvöfaldur dálkur |
|
Eyða línu með auðkenni 3 |
|
Eyða dálkum A og D |
|
Skrifa töflu á skjá, með HTML-sniði |
|
Skrifa töflu á skjá með textasniði |
|
Skrifa HTML-töflu með sniði |
|
Raða töflu eftir gildunum í dálki |
|
Raða töflu í minnkandi röð |
|
Skila töflu yfir meðaltöl, staðalfrávik o.fl. |
|
Sameina |
|
Dálki „nfn“ breytt í venjulegan Python lista |
|
Hluttöflu breytt í NumPy fylki |
|
Önnur leið til að búa til NumPy fylki |
Æfing
Eyðið flokki að eigin vali úr kosningaúrslitatöflunni, þó ekki þeims síðasta.
Prófið svo að birta línur þar fyrir aftan, annars vegar með loc
og hinsvegar
með iloc
og takið eftir muninum.
|
Stak með gefið nafn |
|
Stak númer nr |
v = np.array(s) |
Runu breytt í NumPy vigur |
s.mean() |
Meðaltal |
s.std() |
Staðalfrávik |
L = list(s.index) |
Venjulegur listi með auðkennum s |
15.4 Innbyggð Python föll og Pandas¶
Oft er hægt að beita algengum innbyggðum Python-föllum á hvort sem er
gagnatöflur eða Pandas-runur beint. Þannig er hægt að finna stærsta stak runu og
fjölda lína í töflu með max(s)
og len(df)
. Annað dæmi er zip
: til að
búa til uppflettitöflu frá listabókstaf í flokk í sýnidæminu í kafla
15.1 má nota U = dict(zip(kosn["Stafur"], kosn["Flokkur"]))
. Það
þarf sem sé ekki nauðsynlega að breyta Pandas-hlutum í venjulega lista áður en
unnið er með þá áfram.
Það sama gildir um bæði NumPy-föll og Matplotlib-skipanir, að þeim má oft beita
beint á Pandas-hluti. Ef df
er ferningslaga og s
hefur rétta lengd þá má
t.d. leysa jöfnuhneppi með la.solve(df, s)
og reikna kvaðratrætur allra
staka með np.sqrt(df)
. Þetta er samt ekki alveg algilt, t.d. er hægt að
reikna sum(df.values)
en ekki sum(df)
. Um notkun Pandas með Matplotlib
er svo rætt í næsta kafla.
15.5 Pandas og teikningar¶
Matplotlib teikniskipanir geta notað dálka í Pandas-töflum sem viðföng. Til dæmis, ef xy.xlsx
hefði tvo dálka, „x“ og „y“, þá mætti teikna línurit af þeim með skipununum:
df = pd.readexcel("xy.xlsx")
plt.plot(df["x"], df["y"])
Í eftirfarandi dæmi eru Pandas-dálkar notaðir sem viðföng í skipanirnar bar
og xticks
.
Sýnidæmi: Kosningaúrslit með Pandas
Hér er dæmi sem teiknar súlurit af kosningaúrslitunum 2017 sem voru á dagskrá í sýnidæmi í grein 15.1:
plt.figure(dpi=100)
kosn = pd.read_excel("http://cs.hi.is/python/kosningar.xlsx")
x = range(len(kosn))
plt.bar(x, kosn["Atkvæði"], color="tomato")
plt.xticks(x, kosn["Stafur"])
plt.ylabel('Atkvæði')
plt.title('Úrslit alþingiskosninga 2017');
Hér er x listinn [0,1,2…9] (það voru 10 framboðslistar). Lista ef liti má finna hér. Forritið teiknar þessa mynd:
15.6 Fleiri Pandas æfingar¶
Til að læra betur á Pandas er tilvalið að beita því til að leysa ýmis verkefni tengd skráavinnslu aftast í þessum fyrirlestrarnótum, t.d. verkefni 11, 15, 16, 19, 23, 27 og 35. Með því gefst tækifæri til að nota ýmsar af þeim skipunum sem gefnar eru í töflunum í kafla 15.3
15.7 Punktritháttur¶
Í Python eru hornklofar notaðir til að tákna gildi í uppflettitöflum eins og við kynntumst í 7. kafla, á svipaðan hátt og Pandas notar hornklofa til að vísa í töfludálka. Í Javascript er hægt að skilgreina hluti (objects) sem svara að mörgu leyti til uppflettitaflna í Python. Þar er hægt að nota hornklofa til að fletta upp eiginleikum hluta, en maður hefur val og getur líka notað punkt. Eftirfarandi er löglegt Javascript forrit:
let einst = {'nafn': 'Jón', 'aldur': 33}
einst['sími'] = 888-7777
einst.kennitala = '111213-3210'
console.log(einst["nafn"], einst.aldur, einst.sími)
Það sama á svo við um Pandas: Það er hægt að nota punkt til að vísa í dálka í Pandas gagnatöflum. Þetta er nefnt punktritháttur (dot notation). Þannig mætti hafa sýnidæmið í kafla 15.1 svona:
import pandas as pd
kosn = pd.read_excel("http://cs.hi.is/python/kosningar.xlsx")
display(kosn)
n = sum(kosn.Atkvæði)
kosn["Hlutf"] = kosn.Atkvæði/n
display(kosn)
og miðparturinn í sýnidæminu í kafla 15.5 yrði:
x = range(len(kosn))
plt.bar(x, kosn.Atkvæði, color="tomato")
plt.xticks(x, kosn.Stafur)
Það eru ýmsar takmarkanir á punktrithættinum:
það er ekki hægt að nota hann til að bæta við dálkum (
kosn.Hlutf = kosn.Atkvæði/n
dugar ekki)dálknafnið má ekki vera tala, nafn á Pandas-aðferð eða frátekið Python-nafn (t.d. hvorki 37, count eða class)
dálknafnið getur ekki innihaldið bil.
Engu að síður er punktrithátturinn talsvert notaður; hann sparar þrjá stafi miðað við hornklofana og er auðveldari að lesa. Hér er ágæt umræða um málið.