8 CSV
CSV-vorming
CSV (ingl Comma-separated values, komadega eraldatud väärtused) on levinud failivorming erinevate (tekstiliste või arvuliste) andmete hoidmiseks.
Lihtsa CSV-faili sisu võib olla selline:
Albert;Algoritm;2010 Donna;Definitsioon;1998
Olemuselt on CSV tavaline tekstifail, mille failivorming on “.csv“. Faili iga rida sümboliseerib midagi: üht isikut, veebilehte, termomeetri näitu kindlal ajahetkel vms. Ühe CSV-faili piires on igal real samalaadsed väärtused, näiteks isikute korral eesnimi, perenimi, sünnikuupäev. Ühel real olevad väärtused on üksteisest eraldatud kindla sümboliga. Klassikaliselt on eraldaja olnud koma (sellest ka failivormingu nimetus), kuid praktilisem võib olla kasutada näiteks semikoolonit (eestikeelsed murdarvud kirjutatakse tihti komaga, mis tekitaks lugemisel probleeme).
CSV-faili lugemine tavafailina
Me võime CSV-faili avada nagu iga teise sisendfaili ning selle ridu tekstina töödelda:
fail = open("minufail.csv", encoding="UTF-8")
andmed = []
for rida in fail: # loeme ridahaaval
osad = rida.split(";") # semikoolonitega eraldatud sõne muudame järjendiks
andmed.append(osad)
fail.close()
CSV-faili lugemine mooduliga csv
Kuna CSV-failidega lugemist tuleb tihti ette, on selleks eraldi Pythoni moodul nimega csv. Tegemist on Pythoni standardmooduliga, mille kasutamine tuleb programmi alguses näidata
abil. Selle abil saame CSV-faili lugeda nii:import csv
import csv
andmed = []
csvfail = open('minufail.csv', encoding='UTF-8')
loetudCSV = csv.reader(csvfail, delimiter=';')
for rida in loetudCSV:
andmed.append(rida)
csvfail.close()
Eelnevas näites polnud mooduliga kood eriti lihtsam, kuid keerukamates oludes on mooduli kasutamine rohkem tulus.
Avalikud andmed
Väga palju andmeid elust enesest on tegelikult täiesti vabalt kättesaadavad ja kasutatavad. Eesti kohta leiab huvitavaid andmeid näiteks statistikaameti veebilehelt.
Näiteks leidub statistikaameti kodulehel andmeid Eesti rahvastiku soolise koossesisu kohta erinevates vanuserühmades.
Selle tabeli põhjal saaks lahendada erinevaid ülesandeid. Näiteks saab leida:
- mis vanuses elanikke on kõige rohkem,
- mis vanuserühmas on meeste ja naiste arvuline erinevus kõige suurem,
- teatud vanuserühma elanike arvu.
Haridusteemalisi andmeid saab Haridussilmast. Haridussilmast võiksime leida näiteks nelja ülikooli vilistlaste keskmised palgad erialade kaupa. Haridussilmast saab andmeid alla laadida küll ainult (Exceli) xls-vormingus, kuid tabeltöötlusprogrammis saab selle faili ka csv-vormingusse salvestada.
Andmetöötlus: Tartu rahvastik
Järgmise näite puhul püüame teada saada, mis aastatel on Tartu elanike arv kasvanud. Statistikaameti veebilehelt saab Tartu elanike arvud kätte järgmiste valikutega: Statistika andmebaas -> Rahvastik -> Rahvastikunäitajad ja koosseis -> Rahvaarv ja rahvastiku koosseis -> RV0282 Rahvastik soo, vanuserühma ja haldusüksuse või asustusüksuse liigi järgi, 1. jaanuar (otselink).
Andmete salvestamisel on võimalik valida, mis kujul me neid faili tahame. Hetkel on sobiv Ilma pealkirjata Semikooloneraldusega pealkirjata tekst (.csv). Nii saame faili RV0282sm.csv, mille esimene rida on
"..Tartu linn";"Mehed ja naised";"2000";106200
Näeme, et meid eriti huvitavad andmed on rea lõpus mõnevõrra erineval kujul – aastaarvul on jutumärgid ümber ja elanike arvul mitte. Kui nüüd eeltoodud moel fail sisse lugeda ja rida osadeks jaotada, siis saame, et osad[2]
on sõne ""2000""
ja osad[3]
on sõne "106200"
. Meie tahame neid mõlemaid täisarvudena, mida annab funktsioon int
. Küll aga tuleb ""2000""
puhul arvu ümbert sõnesisesed jutumärgid eemaldada, mida saame teha funktsiooni
abil: strip
.osad[2].strip('"')
Järgmises programmis paneme saadud andmed järjendisse nii, et ühes reas (
) on kõik aastaarvud ja teises (andmed[0]
) kõik elanike arvud. Failis olid erinevate aastate andmed erinevatel ridadel.andmed[1]
fail = open("RV0282sm.csv", encoding="UTF-8")
andmed = [[], []]
for rida in fail: # loeme ridahaaval
osad = rida.split(";") # semikoolonitega eraldatud sõne järjendiks
andmed[0].append(int(osad[2].strip('"')))
andmed[1].append(int(osad[3]))
fail.close()
Kui nüüd tahame leida aastad, mil elanike arv kasvas, siis võrdleme iga aasta korral, kas järgmise aasta elanike arv on suurem. Kuna andmed on 1. jaanuari seisuga, siis täpselt ühe aasta kaupa saamegi muudatusi nii jälgida.
for i in range(len(andmed[0]) - 1):
if andmed[1][i + 1] > andmed[1][i]:
print(andmed[0][i])
Siin on oluline, et tsükkel lõpeb eelviimase elemendiga, sest viimasel elemendil poleks järgmist (
), millega võrrelda.andmed[1][i + 1]
Sarnase tulemuse võime saavutada ka mooduliga csv:
import csv
andmed = [[], []]
csvfail = open('RV0282sm.csv', encoding='UTF-8')
loetudCSV = csv.reader(csvfail, delimiter=';')
for rida in loetudCSV:
andmed[0].append(int(rida[2]))
andmed[1].append(int(rida[3]))
csvfail.close()
for i in range(len(andmed[0]) - 1):
if andmed[1][i + 1] > andmed[1][i]:
print(andmed[0][i])
CSV-faili kirjutamine
CSV-faili kirjutatakse nii nagu tavalisse faili, kuid iga salvestatud väärtuse vahele peaks lisama semikooloni. CSV-faili kirjutatud andmeid on mugav avada tabelitöötlusprogrammiga.
Oletame, et meil on ühes järjendis linnade nimed ja teises vastavates linnades olev temperatuur, siis saamejärjendi elemendid kirjutada faili CSV-formaadis selliselt:
linnad = ["Tartu", "Tallinn", "Pärnu"]
temperatuurid = [3, 5, 4]
f = open("andmed.csv", "w")
for i in range(len(linnad)):
f.write(linnad[i] + ";" + str(temperatuurid[i]) + "\n")
f.close()