Behandling av store datamengder i Python
Når vi skal jobbe med store sett med data, er programmering eit nyttig verktøy. Mykje kan òg gjerast i rekneark, men her skal vi sjå på korleis vi kan bruke Python til å behandle store datasett.
Når vi skal behandle data i Python, er det første vi må gjere, å laste ned ei fil med dataa og lagre ho i eit formålstenleg format. Gode format å jobbe med er .txt og .csv. Når vi lastar ned filer med stort talmateriale frå ulike statistikkar, er det ofte lurt å bruke .csv.
Vi skal sjå på nokre data om mediebruk frå Statistisk sentralbyrå (SSB). Du finn datasettet som ei nedlastbar fil nedst på denne sida, men prøv helst å laste ned fila sjølv, på nettsida https://www.ssb.no/statbank/table/04495/.
Datasettet som er brukt i dømet, er henta frå Statistikkbanken til SSB. Datasettet inneheld opplysningar om kor mange minutt ein gjennomsnittsnordmann brukte på ulike medium per dag dei siste åra. Følg framgangsmåten nedanfor for å velje ut data frå nettsida:
- Gå til nettsida (sjå over).
- Sørg først for at "Minutt brukt til ulike medium ein gjennomsnittsdag" er vald i boksen "Statistikkvariabel".
- Vel deretter alle medietypane i boksen "Medietype" ved å klikke på knappen med grøn hake (eller vel alle manuelt i menyen).
- Vel åra 2010 til 2019 i boksen "År".
- Trykk på knappen "Vis tabell".
Når du har gjort dette, vil nettsida vise ein tabell som du kan sjå utdrag frå nedanfor:
Medium | 2010 | 2011 | 2012 |
---|---|---|---|
Papiravis | 23 | 24 | 21 |
Fjernsyn | 152 | 157 | 131 |
Radio | 81 | 86 | 88 |
Spørsmål
Kva betyr talet 131 i ruta for fjernsyn i året 2012?
For å laste ned ei fil med desse dataa gjer du følgande:
- Vel "Lagre data som..." til venstre for tabellen.
- Vel "Semikolonserparert med overskrift(csv)".
- Trykk "Lagre".
- Kopier fila over til same mappe på pc-en som Python-programma dine ligg i. Det gjer det lettare å referere til fila i programmet som skal bruke ho.
- Endre filnamnet til "ssbmedium.csv".
Python-modulen Pandas bruker vi både til å lese datafila inn i Python og til å behandle dataa etterpå. Pandas organiserer dataa i ein såkalla dataframe (ei dataramme), som er ein tabell med kolonne- og radoverskrifter, ikkje ulikt eit rekneark.
Før vi les datafila inn i Python, kan vi kort sjå på ho med eit reknearkprogram. Bruk datafila du har lasta ned (ssbmedium.csv), eller last ned datafila nedst på denne sida. Opne fila i eit rekneark. Datafila ser slik ut (ikkje alle kolonnane er tekne med):
Det er tre problem med denne datafila:
- Dei to første radene må fjernast.
- Det manglar tal fleire stader. På slike stader står det anten eitt eller to punktum, avhengig av kvifor det manglar tal (sjå forklaring på nettsida med tabellen).
- Kolonneoverskriftene er veldig lange. På biletet over har vi utvida kolonne B slik at vi får med heile overskrifta. Også dei andre talkolonnane har den same lange overskrifta. Vi, derimot, vil berre ha årstala.
Dei to første problema ordnar vi under sjølve innlesinga. Det siste fiksar vi seinare.
Kode for innlesinga
Kopier koden nedanfor og lim han inn i programmeringseditoren du vanlegvis bruker. Pass på at fila har same namn i filstrukturen på pc-en som i programkoden. Køyr programmet. Får du utskrift av dataa? Du får ganske sikkert ei lite lesbar utskrift, men dette kan du ordne seinare.
Forklaring av koden
Først må vi importere modulen Pandas. Ved å importere han som "pd" slepp vi å skrive heile modulnamnet når vi skal referere til han.
Kommandoen vi bruker for å lese inn fila, er "read_csv()". Variabelen data
blir då ein dataframe. Vi må setje inn mange såkalla attributt i kommandoen for at innlesinga skal gå smertefritt:
ssbmedium.csv
: Her skriv vi filnamnet (og eventuell adresse) på datafila som skal lesast.index_col = 0
: ((Attributtet "index_col" får verdien 0.) Her fortel vi Python at første kolonne skal vere overskrifter.skiprows
= (0, 1)
: Dette betyr at dei to første radene (rad nummer 0 og 1) i fila skal hoppast over. (Hugs at Python byrjar nummerering på null.)- Vi deler opp den lange kodelinja med teiknet
\
. Hugs at neste linje må rykkast inn. sep = ";"
: Dersom vi ser på datafila med ein enkel editor, som for eksempel Notisblokk i Windows, vil vi finne at alle dataa er åtskilde frå kvarandre med semikolon. Dette attributtet fortel programmet at semikolon betyr "nytt tal".na_
values
= [".", ".."]
: Her listar vi opp det som skal vurderast som manglande data eller "ikkje-data". Akkurat i denne fila er manglande data symboliserte ved anten eitt eller to punktum, men kva for teikn som blir brukte, kan variere frå fil til fil. Attributtetna_
values
sørger for at teiknet blir omsett til "NaN", eller "Not_a_Number" i den interne datatabellen. Då skaper det ikkje meir krøll under den vidare behandlinga.encoding
= "latin-1"
: Dersom vi legg til dette attributtet, tek programmet høgde for at datafila inneheld skandinaviske bokstavar som æ, ø eller å. Dersom dette ikkje fungerer, prøv verdien"utf-8"
.
Til slutt skriv vi ut innhaldet av variabelen data
på vanleg måte med kommandoen print(data)
.
Dessverre blir utskrifta dårleg lesbar på grunn av dei lange kolonneoverskriftene ("Minutt brukt til ..."). Vi skal erstatte overskriftene med berre årstala. Det gjer vi ved å lage ei liste med årstala og rett og slett skrive inn dei nye kolonneoverskriftene i variabelen data
. Sidan vi har statistiske data for kvart år, kan vi bruke ei for-lykkje til å generere lista, som vi her har kalla K
for kolonneoverskrift.
Kopier inn koden over rett før print()-kommandoen. Det kan hende at det blir med litt "rusk" under kopieringa; dette må i så fall fjernast i programmeringseditoren. I for-lykkja blir det for kvar runde lagt til eit tal i lista K
som er 1 større enn det førre. I programkoden har vi lagt til kommentarar ved hjelp av teiknet #
.
Får du ein meir lesbar tabell no, om du legg til koden over før du skriv ut innhaldet av variabelen data
? Det kan hende at du berre får utskrift av tala for dei 3–4 første åra og for dei 3–4 siste. Det er heilt normalt. No er dataa klar for meir behandling!
Modulen Pandas har ein eigen kommando for å hente ut ulike statistiske mål i ein dataframe. Vi skriv følgande:
Resultatet skal likne på tabellen nedanfor, der vi berre har skrive inn tala for året 2010.
2010 | |
---|---|
count | 11.000000 |
mean | 44.727273 |
std | 48.203923 |
min | 1.000000 |
25% | 8.000000 |
50% | 23.000000 |
75% | 78.500000 |
max | 152.000000 |
Forklaring på dataa
- count
- talet på observasjonar vi har i kolonnen
- mean
- gjennomsnittet av verdiane i kolonnen
- std
- standardavviket i kolonnen. Standardavviket fortel oss noko om kor stor spreiing det er i datamaterialet. Viss standardavviket er stort, betyr det at vi har mange observasjonar som ligg langt unna gjennomsnittet. Viss vi bevegar oss eitt heilt standardavvik opp og ned frå gjennomsnittsverdien, skal vi ha ca 2/3 av alle observasjonane i dette intervallet.
- min
- minimumsverdien i kolonnen
- 25%
- den nedste kvartilen. Dette talet fortel oss at 25 prosent av observasjonane i kolonnen er lågare enn denne verdien.
- 50%
- medianen. Dette talet fortel oss at 50 prosent av observasjonane i kolonnen er lågare enn denne verdien.
- 75%
- den øvste kvartilen. Dette talet fortel oss at 75 prosent av observasjonane i kolonnen er lågare enn denne verdien (og at 25 prosent av observasjonane er høgare enn denne verdien).
- max
- maksimumsverdien i kolonnen
Modulen Pandas har sin eigen plot()-kommando, som i sin tur bruker modulen Pyplot sin plot()-kommando (sjå teorisida "Teikne grafar med pyplot") til å lage framstillinga.
Vi ønsker å lage ei framstilling der vi ser korleis utviklinga har gått for dei ulike medietypane. Det betyr at vi ønsker å ha årstala på -aksen.
Vi skriv følgande for å lage eit linjediagram av tala i variabelen data
:
Då får vi denne grafiske framstillinga:
Spørsmål
Kva viser denne grafiske framstillinga?
Framstillinga blir feil. Vi kan fikse dette ved å byte om på rader og kolonnar i variabelen data
før vi lagar plottet. Dette gjer vi med kommandoen transpose, sjå linje 1 i koden nedanfor. I tillegg ønsker vi å unngå at forklaringa kjem oppå grafikkfeltet. Det fiksar vi ved å legge til metoden "legend" til plot()-kommandoen og la attributtet "bbox_to_anchor" få verdien "(1, 1)", som er koordinatane til øvre høgre hjørne av plottet. Sjå linje 2.
Då får vi denne figuren:
No vart framstillinga riktig fordi vi køyrde kommandoen "transpose()" som transponerer tabellen ved å la radene bli kolonnar. Forklaringa la seg dessutan fint på sida av grafikkfeltet.
Spørsmål
Kvifor sluttar grafen for heime-pc i året 2014, mens grafen for digitale spel startar i 2016?
Plotting av enkeltkolonnar
Dersom vi ønsker å samanlikne bruken av fjernsyn med bruken av internett, kan vi lage ein ny dataframe som berre inneheld dei kolonnane vi er interesserte i. Først vel vi ut radene med fjernsyn og internett frå dataframe-variabelen data
, så legg vi dei i ein ny dataframe, og til slutt transponerer vi denne. Vi skriv følgande:
Her lagar vi ein ny dataframe-variabel utdrag
som berre inneheld rad nummer 1 og 10 frå variabelen data
, ved hjelp av metoden iloc.
NB: Hugs å fjerne tidlegare kommandolinjer med "transpose()" frå programmet ditt når du set inn linjene over.
Spørsmål
Kvifor brukte vi tala 1 og 10 i argumentet til metoden iloc?
Spørsmål
Er det tilfeldig at tala 1 og 10 er argument både i range-funksjonen i for-lykkja og i kommandoen med iloc?
Vi kan forbetre den grafiske framstillinga ved hjelp av modulen Pyplot.
Spørsmål
Kva kan vi gjere dersom vi vil forbetre den grafiske framstillinga av tala for fjernsyn og internett? Kva manglar i figuren?
Oppgåve
Kommandoane nedanfor endrar den grafiske framstillinga i samsvar med forslaget vårt. Skriv dei inn og observer kva som skjer. Prøv å forklare kva kvar av dei fire kommandoane gjer.
Skriv øvst i programkoden (om du ikkje alt har gjort det):
Dette må du gjere for å kunne bruke funksjonane i Pyplot i programmet. Skriv så nedst i programkoden:
Sjå òg teorisida "Teikne grafar med Pyplot" om du vil lese meir om forbetra framstilling av grafar.
Filer
Oppgåve
Lag ei tilsvarande grafisk framstilling der du samanliknar to eller tre ulike medietypar som du kan tenke deg å studere nærare.