Tabelarni i grafički prikaz podataka¶
U primeru iz prethodnog dela ove lekcije, tabelu smo ispisali koristeći naredbu:
print(df)
Pogledajmo kakav rezultat dobijamo kada izvršavanje ćelije samo vrati vrednost od df, umesto da je ispiše pomoću print(df). Da bismo to postigli, potrebno je da izmenimo kod u ćeliji tako da namesto prethodne linije koda unesemo samo naziv promenljive:
Podsećamo vas da poslednji izraz u ćeliji određuje vrednost koju vraća izvršavanje ćelije. U ovom slučaju, to je vrednost promenljive df.
Na ovaj način, u Jupyter svesci dobijamo prikaz tabelarnih podataka koji je pregledniji nego kada tabelu ispišemo pomoću funkcije print().
Ako želimo da prikažemo samo prvih nekoliko redova tabele, možemo koristiti df.head():
Kao što se može zaključiti iz gore prikazanog, metoda head() podrazumevano izdvaja prvih pet redova tabele. Međutim, broj redova možemo i zadati kao argument. Na primer, prva tri reda izdvajamo pomoću df.head(3).
Ako želimo da izdvojimo poslednjih nekoliko redova, umesto head() koristimo metodu tail().
Pre nego što nastavimo s lekcijom, izdvojićemo samo prvi red pomoću df.head(1) kako bi tabela zauzimala manje prostora.
Prethodno smo naveli da je print() funkcija, a da su head() i tail() metode. U pitanju su slični koncepti. Ipak, važno je da znamo glavnu razliku između funkcije i metode:
Prilikom poziva funkcije, svi argumenti stoje unutar zagrada, kao u primeru:
max(2, 3)iliprint(df)Prilikom poziva metode, jedan argument stoji sa leve strane i razdvaja se tačkom, dok ostali (ako ih ima) stoje unutar zagrada, kao u primeru:
df.tail(3)ilidf.head()
Uz to, obično se kaže da se metode head() i tail() izvršavaju na objektu df.
Pojam metode potiče iz objektno-orijentisanog programiranja, ali kako se objektno-orijentisanim programiranjem nećemo baviti u ovom kursu, zadržaćemo se na gornjem objašnjenju.
Grafički prikaz podataka¶
U nastavku želimo da na osnovu tabelarnih podataka kreiramo grafikon. Vraćamo se na tab u kom nam je otvoren ChatGPT i zadajemo upit:
treba mi linijski grafikon koji prikazuje kretanje temperature
Važno je da ovaj zahtev postavimo u okviru istog četa u kom smo postavili i početni zahtev ChatGPT-u. To jest, važno je da primer Python koda iz prethodnog odgovora bude uzet u obzir.
ChatGPT je generisao novi kod koji ćemo kopirati u ćeliju Jupyter sveske.
import pandas as pd
import matplotlib.pyplot as plt
# Kreiranje podataka
data = {
"Dan": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
"Temperatura (°C)": [22, 24, 19, 23, 25, 20, 21, 22, 24, 23],
"Vlažnost (%)": [65, 70, 75, 60, 55, 80, 78, 72, 68, 64]
}
# Kreiranje DataFrame-a
df = pd.DataFrame(data)
# Kreiranje linijskog grafikona
plt.plot(df["Dan"], df["Temperatura (°C)"], marker='o', linestyle='-', label='Temperatura')
# Dodavanje naslova i oznaka osi
plt.title("Kretanje temperature tokom 10 dana")
plt.xlabel("Dan")
plt.ylabel("Temperatura (°C)")
# Dodavanje legende
plt.legend()
# Prikazivanje grafikona
plt.grid(True)
plt.show()
ChatGPT je u ovom odgovoru dao kompletan kod, dopunjen sa linijama za crtanje grafikona. Označene su linije koda koje su iste kao u prethodnom primeru.
Nešto slično se dešava i kada nam ChatGPT pomaže u pisanju nekog teksta. Na primer, umesto da nam ponudi formulaciju jedne rečenice koja nam je potrebna, ChatGPT nam odgovara novom varijantom celokupnog teksta, koja obuhvata kako pređašnji sadržaj tako i dodatu rečenicu.
Naime, kao što je i nama često lakše da sve ispričamo od početka nego da nastavimo od sredine, tako i ChatGPT bolje funkcioniše kada kontekst ponovi u novom odgovoru. Ovo nije specifično samo za ChatGPT, već za velike jezičke modele uopšte.
Razume se, možemo tražiti od ChatGPT-a i da nam izdvoji linije koda koje idu u novu ćeliju. Međutim, nije na odmet da sami to uradimo budući da svakako treba da budemo upoznati sa onim što stoji u kodu.
U ovom slučaju, iz nove ćelije treba jednostavno da obrišemo linje koda koje su već prethodno izvršene. U pitanju su promenljiva df i tabelarni podaci. Te linije koda smo već označili. Dakle, u novoj ćeliji ostaje:
import matplotlib.pyplot as plt
# Kreiranje linijskog grafikona
plt.plot(df["Dan"], df["Temperatura (°C)"], marker='o', linestyle='-', label='Temperatura')
# Dodavanje naslova i oznaka osi
plt.title("Kretanje temperature tokom 10 dana")
plt.xlabel("Dan")
plt.ylabel("Temperatura (°C)")
# Dodavanje legende
plt.legend()
# Prikazivanje grafikona
plt.grid(True)
plt.show()
Izvršavanjem ćelije dobijamo:
U nastavku ćemo objasniti pojedinačne linije koda. Na početku imamo:
import matplotlib.pyplot as plt
Ovom linijom smo importovali modul matplotlib.pyplot i naznačili da ćemo za taj modul nadalje koristiti skraćeni naziv plt. Podsećamo vas da smo paket matplotlib instalirali jer smo znali da će nam u nekom trenutku biti potreban. Upravo koristimo modul iz tog paketa kako bismo nacrtali grafikon.
Glavna linija koda za crtanje grafikona je:
plt.plot(df["Dan"], df["Temperatura (°C)"], marker='o', linestyle='-', label='Temperatura')
Ovom linijom smo pozvali funkciju plot() iz modula matplotlib.pyplot. Budući da plt predstavlja skraćeni naziv za modul matplotlib.pyplot, plt.plot() jeste poziv funkcije iz tog modula.
Pojašnjenje
Upravo smo istakli da je plt.plot() poziv funkcije iz modula, a ranije smo naglasili da je df.head() poziv metode. Budući da plt predstavlja modul, za plt.plot() kažemo da je poziv funkcije iz modula, a ne poziv metode. Premda vam trenutno nije od posebnog značaja da li nešto zovemo metodom ili funkcijom, ne treba da vas zbunjuje što koristimo različite termine da označimo nešto što slično izgleda.
U pozivu funkcije plt.plot(), pojavljuju se sledeći argumenti:
df["Dan"]− kolona za podatke po x-osidf["Temperatura (°C)"]˙− kolona za podatke po y-osimarker='o'− na linijskom grafikonu su markeri u obliku kružićalinestyle='-'− koristimo običnu punu linijulabel='Temperatura'− naziv koji se prikazuje u legendi
Narednih nekoliko linija koda podešava detalje u izgledu grafikona.
Na kraju stoji:
plt.show()
Ovom linijom smo tražili da se grafikon prikaže. Prethodne linije koda su zapravo definisale grafikon, a plt.show() na kraju prikazuje to što je definisano.
U konkretnom slučaju, grafikon bi se prikazao i da nismo koristili plt.show(), jer će Jupyter automatski prikazati grafikon koji je započet. Međutim, nije preporučljivo oslanjati se na ovu karakteristiku Jupyter-a, već se dobrom praksom smatra korišćenje plt.show().
Za argumente marker='o', linestyle='-' i label='Temperatura' kažemo da su imenovani argumenti, a imena su marker, linestyle i label. Kada bi ti argumenti zamenili mesta, grafikon bi i dalje izgledao isto, jer svaki argument sa sobom nosi svoje ime nezavisno od pozicije na kojoj se nalazi. Za imenovane argumente se u engleskom koristi naziv keyword arguments.
Nasuprot tome, kada bismo zamenili mesta argumentima df["Dan"] i df["Temperatura (°C)"], došlo bi do promene podataka po x, odnosno po y-osi. U ovom slučaju, značenje argumenta je određeno pozicijom, a ne nazivom. Takve argumente zovemo pozicionim argumentima.
Imenovani argumenti su korisni kada u pozivu funkcije imamo mnogo argumenata, jer nam pomažu da izbegnemo greške u redosledu. Međutim, bilo bi zamorno kada bi svaki argument morao da ima naziv čak i ako pozivamo funkcije i metode sa jednim ili dva argumenta. Iz tog razloga, postoje obe vrste argumenata, pa i slučajevi kada se kombinovano koriste, kao u prethodnom primeru poziva metode plot().
Grupisanje svih import naredbi na početak¶
Radi preglednosti i jasnoće, sve importe obično izdvajamo u posebnu ćeliju na početku sveske kako bi nam se nalazili na jednom mestu.
Nakon grupisanja svih import naredbi, sveska izgleda ovako:
Nazivi kolona¶
Pre nego što izvršimo sve ćelije, unećemo još neke izmene. Naime, imamo kolonu koja se zove Temperatura (°C). Ovaj naziv izgleda lepo kada se ispiše, ali nije praktičan kada moramo da ga otkucamo prilikom referisanja na kolonu, kao što je to slučaj u izrazima poput df["Temperatura (°C)"]. Naročito je oznaka za stepen (°) u nazivu nepraktična, jer je ne možemo jednostavno uneti sa tastature. Iz tog razloga, naziv kolone menjamo u Temperatura_C.
Međutim, izraz plt.ylabel("Temperatura (°C)") možemo zadržati, jer on samo određuje natpis na y-osi grafikona, a ne uvodi naziv koji bismo kasnije morali da koristimo u kodu.
Budući da već pojednostavljujemo nazive kolona, promenićemo i Vlažnost (%) u Vlažnost.
Pošto smo u svaku ćeliju uneli određene izmene, pokrenućemo restartovanje kernel-a sa izvršavanjem svih ćelija kako bismo proverili da li se sve i dalje ispravno izračunava i crta:
Skrolovaćemo do kraja kako bismo se uverili da je generisani grafikon isti kao i prethodni: