Prelazimo u Jupyter¶
Otvaramo JupyterLab u virtuelnom okruženju projekta, kao što smo u više navrata činili u prethodnim lekcijama, počevši od lekcije o instalaciji. U JupyterLab-u pravimo novu svesku podaci-skole.ipynb.
🔍 Podsetnik
U video lekciji možete da ispratite sve korake u radu sa alatima koje ne navodimo detaljno u tekstu.
U prvoj ćeliji sveske ćemo staviti naslov. Ako je od ranije ostala otvorena neka druga sveska, zatvorićemo je.
Da se podsetimo, naslov unosimo u Markdown notaciji kao # Škole i odeljenja, a ćeliju prebacujemo u tip Markdown. Na prethodnoj slici vidimo kako na kraju izgleda formatiran naslov.
U drugom tabu brauzera otvorićemo ChatGPT kako bi nam bio lako dostupan kada ga kasnije budemo koristili.
Prvo što treba da uradimo u Jupyter svesci je da učitamo podatke iz Excel fajla. U File Browser-u JupyterLab-a prikazani su fajlovi iz projektnog foldera, uključujući i Excel fajl. Da ga ne bismo prekucavali, kopiraćemo naziv fajla tako što ćemo u meniju koji se otvara desnim klikom odabrati Copy Path.
Preći ćemo u ChatGPT i tražiti:
Treba mi linija python koda koja učitava Excel tabelu iz „Osnovno obrazovanje - Odeljenja i razredi.xlsx”
Prilikom kucanja našeg zahteva, pejstovali smo prethodno kopirani naziv fajla.
ChatGPT vam može dati sledeći odgovor:
🔍 Podsetnik
Kažemo „može dati” jer ChatGPT ne daje uvek isti odgovor za isto pitanje. Ako procenite da vam odgovor koji ste dobili nije od koristi, pokušajte da preformulišete ili precizirate vaše pitanje tako da prevaziđete početno „nerazumevanje”.
Primećujemo u prvoj liniji odgovora da ChatGPT predlaže korišćenje biblioteke pandas, što nam odgovara.
U odgovoru su date dve varijante i obe koriste poziv funkcije pd.read_excel(). U drugoj varijanti je pored naziva fajla naveden i argument sheet_name kojim se precizira radni list iz koga se učitavaju podaci za slučaj da to nije prvi radni list u Excel dokumentu. Naš dokument, ako se podsetimo, ima više radnih listova, ali je radni list sa podacima ostao na prvom mestu, pa ćemo u Jupyter ćeliji izvršiti:
import pandas as pd
df = pd.read_excel("Osnovno obrazovanje - Odeljenja i razredi.xlsx")
df
🔍 Podsetnik
Na kraj Jupyter ćelije često dodajemo liniju sa nazivom promenljive čiju vrednost želimo da vidimo prikazanu.
Rezultat izvršavanja ćelije vidimo na sledećoj slici.
Kada ima puno redova, kao što je ovde slučaj, Jupyter podrazumevano prikazuje prvih pet i poslednjih pet redova.
Međutim, iz Excel-a je učitano skoro 200 hiljada redova, koliko ih i ima u tabeli. To može potrajati između 15 sekundi i minut u zavisnosti od brzine procesora računara. U svakom slučaju, trebalo je strpljivo sačekati da se prethodno izvršavanje završi.
Kada smo iste ove podatke analizirali u Excel-u, na kraju smo koristili filter po školskoj godini i vrsti ustanove. Isto ćemo da uradimo i sada. Primenićemo znanje iz prethodne lekcije o tome kako da iz data frame-a izdvojimo redove prema određenim uslovima. Po uzoru na primer iz prethodne lekcije, izraz koji izdvaja redove za školsku 2024/2025. godinu i za „obične” osnovne škole bi izgledao ovako:
df[(df["Školska godina"]=="2024/2025") & (df["Vrsta ustanove"]=="Основна школа")]
U Python-u dvostruki znak jednakosti (==) označava logički operator za jednakost, dok se jednostruki znak jednakosti koristi za dodelu vrednosti. Logički uslov da je školska 2024/2025. godina glasi:
df["Školska godina"]=="2024/2025"
A logički uslov da je vrsta ustanove „obična” osnovna škola glasi:
df["Vrsta ustanove"]=="Основна школа"
U oba logička uslova, prvo smo izdvojili kolonu iz data frame-a df, a zatim smo primenili logički operator poredeći tu kolonu sa konkretnom vrednošću. Na kraju, ta dva logička uslova povezujemo u složeni logički uslov koristeći logički operator „i”, isto kao u primeru iz prethodne lekcije.
Rezultat izvršavanja izraza koji bi trebalo da izdvoji kolone je:
Međutim, došlo je do greške. U Jupyter svesci se tada obično ispiše dosta informacija, te treba prepoznati one koje ukazuju na uzrok greške. U ovom slučaju, u pitanju su sledeće informacije:
① greška u okviru izraza df["Vrsta ustanove"],
② KeyError: 'Vrsta ustanove' znači da nije pronađeno ništa pod oznakom 'Vrsta ustanove'.
To zajedno znači da u df ne postoji kolona pod nazivom Vrsta ustanove.
🔍 Podsetnik
U Python-u se za stringove mogu koristiti i dvostruki i jednostruki navodnici, što znači da je svejedno da li stoji "Vrsta ustanove" ili 'Vrsta ustanove'.
Ako pažljivo pogledate naziv kolone u prikazu učitanih podataka, nećete pronaći grešku u kucanju. Da bismo rešili problem, moraćemo preciznije da proverimo nazive kolona u tabeli.
Postavićemo ChatGPT-u sledeće pitanje:
Kako da vidim tačne nazive kolona u pandas dataframe
ChatGPT vam može dati sledeći odgovor:
Dakle, potrebno je da izvršimo df.columns. Na sledećoj slici prikazan je rezultat izvršavanja u Jupyter svesci.
Uočavate li razliku? U nazivu kolone se na kraju potkrao razmak koji nismo mogli da primetimo ranije. Nije ga primetio ni onaj ko je kucao naziv. I ovakve stvari mogu da se dese i da budu uzrok greške.
Bolje bi bilo da preimenujemo kolonu data frame-a, nego da nastavimo da koristimo naziv sa razmakom na kraju. Pitaćemo ChatGPT:
Kako da preimenujem kolonu
Moguć odgovor je:
Pošto će možda biti potrebno da preimenujemo i druge kolone, iskoristićemo varijantu koda koja nam omogućava da preimenujemo više kolona odjednom:
df = df.rename(columns={"StariNaziv1": "NoviNaziv1", "StariNaziv2": "NoviNaziv2"})
Pri čemu ćemo staviti konkretne nazive:
df = df.rename(columns={"Vrsta ustanove": "Vrsta ustanove ", " Vrsta Osnivaca": "Vrsta Osnivaca",
"Ukupan broj ucenika": "Broj ucenika"})
Pored suvišnog razmaka na kraju Vrsta ustanove, primetili smo i suvišan razmak na početku Vrsta Osnivaca. Takođe, u nazivu Ukupan broj ucenika, reč „ukupno” je suvišna sada kada je to jedina kolona sa brojem učenika.
Objasnićemo šta znači vrednost argumenta columns:
{"Vrsta ustanove": "Vrsta ustanove ", " Vrsta Osnivaca": "Vrsta Osnivaca",
"Ukupan broj ucenika": "Broj ucenika"}
Za razliku od uglastih zagrada koje oivičavaju listu, vitičaste zagrade oivičavaju strukturu podataka koju zovemo rečnik (eng. dictionary). Rečnik čine parovi ključ−vrednost. U konkretnom primeru, vidimo tri takva para. Kažemo da se ključ „preslikava” u vrednost ili da se vrednost „pridružuje” ključu.
Kada liniju koda koja preimenuje kolone izvršimo u Jupyter svesci, promenljiva df će sadržati data frame sa promenjenim nazivima kolona.
Ako ponovo izvršimo ćeliju koja je prethodno dala grešku, dobićemo rezultat:
Vidimo da sada u rezultatu imamo nešto više od 31 hiljade redova, što je znatno manje od skoro 200 hiljada redova, koliko je sadržao početni data frame. Strelica na prethodnoj slici ukazuje na to da smo se, nakon izmene sadržaja promenljive df, vratili da izvršimo ćeliju iznad. To znači da u ovom slučaju redosled izvršavanja ne prati redosled ćelija. Takav metod nije pogrešan i može biti praktičan, ali treba da budemo svesni da nećemo dobiti isti rezultat kada sledeći put budemo iz početka izvršili sve ćelije redom.
Naime, ako bismo sada restartovali kernel i izvršili sve ćelije iz početka, opet bi na istom mestu došlo do greške u vezi sa nazivima kolona, jer preimenovanje kolona stoji da bude izvršeno kasnije.
Kada uskladimo redosled ćelija, uklonimo ćeliju df.columns koja nam više nije potrebna i pokrenemo izvršavanje svih ćelija iz početka, dobićemo:
Na prethodnoj slici je prikazan trenutak u kome traje učitavanje Excel tabele, što vidimo po zvezdicama na mestu rednih brojeva ćelija čije izvršavanje nije završeno. Takođe, vidimo da smo u poslednjoj ćeliji kreirali novu promenljivu df2024, kojoj smo dodelili data frame sa izdvojenim redovima.
Izvršavanje će ovog puta biti uspešno, jer se preimenovanje kolona vrši neposredno nakon učitavanja.
Time smo uredno složili ono čime smo se bavili do sada:
importovali smo potrebne pakete,
učitavali smo podatke,
čistili smo učitane podatke,
filtrirali smo deo podataka koji nam treba za dalji rad i smestili rezultat u novu promenljivu.
U praksi ćete, pored preimenovanja kolona, primenjivati različite metode za čišćenje podataka. Tokom tog procesa utvrdite nepravilnosti u podacima koje koristite i pokušajte da ih ispravite za potrebe dalje analize.