Pandas loc i iloc: Potpuni vodič za indeksiranje DataFrame-ova u Pythonu

Praktičan vodič kroz razlike .loc i .iloc u Pandas 2.2 — primjeri koda, česte greške, boolean maske i savjeti za brže i sigurnije indeksiranje DataFrame-ova.

Pandas .loc vs .iloc 2026: Vodič za Indeksiranje

Ako ste ikad radili s Pandasom dulje od jednog popodneva, vjerojatno ste se barem jednom zapitali: "Zašto se ovaj redak ponaša drugačije nego što sam očekivao?" U devet od deset slučajeva odgovor leži u tome kako ste indeksirali DataFrame. Razlika između .loc i .iloc djeluje sitno, ali zna napraviti razliku između koda koji radi predvidljivo i koda koji tiho vraća krive rezultate (a to je, iskreno, najgora vrsta bugova).

U ovom vodiču idemo detaljno kroz oba selektora — kako se ponašaju, gdje griješe i početnici i iskusniji korisnici, te što se promijenilo s Pandas 2.2. Sve s primjerima koje možete kopirati i odmah testirati.

Što su .loc i .iloc i koja je razlika

Pandas vam zapravo daje dva potpuno različita načina da kažete "želim ove podatke":

  • .loc — indeksiranje pomoću labela. Koristi imena redaka i stupaca, a kod raspona uključuje i gornju granicu (da, to znači da "a":"c" vraća tri retka, ne dva).
  • .iloc — indeksiranje pomoću cjelobrojne pozicije. Klasično 0, 1, 2... s ponašanjem identičnim Pythonovom list slicing-u (gornja granica isključena).

Najlakše je razliku zapamtiti kroz jedno pitanje: "Tražim li redak po imenu ili po redoslijedu?" Ako po imenu — .loc. Ako po redoslijedu — .iloc. Toliko.

Brza usporedba u tablici

Karakteristika.loc.iloc
Tip indeksiranjaLabel-basedInteger position-based
Uključuje gornju granicu?DaNe
Boolean maskeDaNe (samo nizovi pozicija)
Funkcionira s nizom imenaDaNe
Funkcionira s callableDaDa

Priprema DataFrame-a za primjere

Prije nego krenemo s primjerima, napravimo mali DataFrame s kojim ću se vraćati kroz cijeli članak. Namjerno sam stavio slovne oznake umjesto standardnog 0–4 indeksa — upravo zato da razlika između .loc i .iloc bude jasna kao dan.

import pandas as pd
import numpy as np

data = {
    "ime": ["Ana", "Marko", "Iva", "Petar", "Lana"],
    "grad": ["Zagreb", "Split", "Rijeka", "Osijek", "Zadar"],
    "godine": [28, 34, 22, 41, 30],
    "placa": [4200, 5100, 3800, 6700, 4900],
}

df = pd.DataFrame(data, index=["a", "b", "c", "d", "e"])
print(df)

Rezultat:

     ime    grad  godine  placa
a    Ana  Zagreb      28   4200
b  Marko   Split      34   5100
c    Iva  Rijeka      22   3800
d  Petar  Osijek      41   6700
e   Lana   Zadar      30   4900

Korištenje .loc – indeksiranje pomoću labela

Odabir jednog retka

# Odabir retka s labelom "c"
df.loc["c"]
# ime         Iva
# grad     Rijeka
# godine       22
# placa      3800

Odabir više redaka

# Lista labela
df.loc[["a", "c", "e"]]

# Raspon labela (UKLJUČUJE oba kraja!)
df.loc["b":"d"]

Pažnja: df.loc["b":"d"] vraća redove b, c i d. Ovo je jedna od najvećih razlika u odnosu na klasični Python slicing i, iz mog iskustva, prva stvar koja zbuni ljude koji dolaze iz NumPy svijeta.

Odabir redaka i stupaca istovremeno

# Sintaksa: df.loc[redak, stupac]
df.loc["a", "grad"]              # "Zagreb"
df.loc["a":"c", ["ime", "placa"]]
df.loc[:, "godine"]              # cijeli stupac kao Series

Boolean maskiranje s .loc

Ovo je, po meni, najmoćnija primjena .loc — filtriranje po uvjetu. Vjerojatno ćete ovo koristiti svakodnevno:

# Svi koji imaju više od 4500 plaće
df.loc[df["placa"] > 4500]

# Kombinacija uvjeta s odabirom stupaca
df.loc[df["godine"] >= 30, ["ime", "grad"]]

Postavljanje vrijednosti pomoću .loc

Kad mijenjate vrijednosti, .loc je gotovo uvijek pravi izbor — uglavnom zato što izbjegava ono famozno SettingWithCopyWarning upozorenje koje će vas inače proganjati:

# Povećajmo plaću svima starijima od 30 godina za 10%
df.loc[df["godine"] > 30, "placa"] *= 1.10

Korištenje .iloc – indeksiranje pomoću pozicije

Odabir po cjelobrojnoj poziciji

# Prvi redak (pozicija 0)
df.iloc[0]

# Posljednji redak
df.iloc[-1]

# Prva tri retka (gornja granica ISKLJUČENA)
df.iloc[0:3]

Odabir redaka i stupaca po poziciji

# Drugi redak, treći stupac
df.iloc[1, 2]                # 34 (godine za Marka)

# Prva dva retka, prva dva stupca
df.iloc[0:2, 0:2]

# Lista pozicija
df.iloc[[0, 2, 4], [0, 3]]

Korištenje step parametra

# Svaki drugi redak
df.iloc[::2]

# Obrnuti redoslijed redaka
df.iloc[::-1]

Najčešće greške i kako ih izbjeći

1. Pretpostavka da je indeks uvijek numerički

Ovo je klasika. DataFrame ima numerički indeks 0–4, vi pišete df.loc[0:2] i dobijete tri retka. Pišete df.iloc[0:2] i dobijete dva. Sve dok je indeks "uredan", ljudi misle da su .loc i .iloc manje-više isto. A onda netko pokrene sort_values() i kod tiho počne vraćati krive rezultate.

df2 = df.reset_index(drop=True)
df2 = df2.sort_values("placa", ascending=False)

df2.loc[0:2]   # redci s indeksima 0, 1, 2 (po originalnom indeksu)
df2.iloc[0:2]  # prva dva retka u trenutnom redoslijedu

2. Chained indexing (lančano indeksiranje)

Izbjegavajte konstrukcije tipa df[df["placa"] > 4000]["ime"] = "Novi". Pandas vam ovdje ne garantira hoće li operacija promijeniti originalni DataFrame ili samo neku kopiju u memoriji koja će odmah nestati. Pouzdano rješenje je jedna .loc operacija:

# Loše (može izbaciti SettingWithCopyWarning)
df[df["placa"] > 4000]["ime"] = "Novi"

# Dobro
df.loc[df["placa"] > 4000, "ime"] = "Novi"

3. Korištenje .iloc s boolean Series

Tu je još jedna zamka: .iloc ne prihvaća pandas boolean Series — samo nizove ili liste. Ako trebate boolean filtriranje, posegnite za .loc ili pretvorite masku u NumPy niz:

mask = df["godine"] > 30

df.loc[mask]              # radi
df.iloc[mask.values]      # radi (kao np.ndarray)
# df.iloc[mask]           # NotImplementedError

Kada koristiti .loc, a kada .iloc

  • Koristite .loc kada radite s imenovanim indeksima, filtrirate po uvjetu ili postavljate vrijednosti.
  • Koristite .iloc kada vam je važan redoslijed (prvi/zadnji redak, svaki n-ti redak) ili kada iterativno obrađujete podatke po pozicijama.
  • Za jednostavan odabir stupca preferirajte df["stupac"] umjesto df.loc[:, "stupac"] — kraće je i čitljivije.

Performanse: .loc vs .iloc vs .at i .iat

Mali, ali korisni dodatak: ako vam treba jedna jedina vrijednost, Pandas ima specijalizirane skalarne selektore koji su znatno brži:

  • .at[label_redak, label_stupac] — label-based, samo skalarna vrijednost
  • .iat[poz_redak, poz_stupac] — position-based, samo skalarna vrijednost
import time

start = time.perf_counter()
for _ in range(100_000):
    val = df.loc["a", "placa"]
print("loc:", time.perf_counter() - start)

start = time.perf_counter()
for _ in range(100_000):
    val = df.at["a", "placa"]
print("at:", time.perf_counter() - start)

Na većini sustava .at je 3–5 puta brži od .loc za skalarni dohvat. Ako u petlji čitate pojedinačne vrijednosti, koristite .at ili .iat. Ili još bolje — pokušajte vektorizirati operaciju i potpuno se riješiti petlje.

Pandas 2.2 novosti i kompatibilnost

U Pandas 2.x dolazi do nekoliko važnih promjena vezanih uz indeksiranje, a većina ide u korist čistoći koda:

  • Copy-on-Write (CoW) postaje zadano ponašanje. Ovo praktički eliminira SettingWithCopyWarning jer Pandas više ne pokušava razlikovati pogled (view) od kopije.
  • PyArrow backend za stringove (dtype="string[pyarrow]") može značajno smanjiti memoriju kad imate puno tekstualnih podataka u indeksu.
  • Većina .loc i .iloc operacija sada vraća kopiju, pa modifikacija rezultata ne mijenja originalni DataFrame.

Ako ne želite čekati Pandas 3.0, CoW možete uključiti odmah:

pd.set_option("mode.copy_on_write", True)

FAQ – Često postavljana pitanja

Koja je razlika između .loc i .iloc u Pandasu?

.loc radi s labelama (imenima redaka i stupaca) i uključuje gornju granicu kod raspona. .iloc radi s cjelobrojnim pozicijama i ne uključuje gornju granicu, baš kao Python list slicing.

Mogu li koristiti .iloc s boolean maskom?

Ne direktno s pandas Series. .iloc prihvaća samo cjelobrojne pozicije, listu pozicija ili NumPy boolean niz. Ako imate pandas boolean Series, koristite .loc[mask] ili pretvorite masku s mask.values i predajte je u .iloc.

Što je brže – .loc ili .iloc?

Za jednu vrijednost obje opcije su sporije od specijaliziranih .at (label) i .iat (pozicija). Za odabir više redaka razlika je zanemariva. Glavna optimizacija je vektorizacija — izbjegavajte petlje kad god je moguće.

Zašto dobivam SettingWithCopyWarning?

Upozorenje se javlja kod lančanog indeksiranja, primjerice df[df.x > 0]["y"] = 1. Pandas ne može jamčiti hoće li se promjena propagirati u originalni DataFrame. Rješenje je jedna .loc operacija: df.loc[df.x > 0, "y"] = 1. U Pandas 2.2+ s uključenim Copy-on-Write upozorenje nestaje jer se ponašanje standardizira.

Mogu li mijenjati više stupaca odjednom s .loc?

Da. Primjer: df.loc[df.x > 0, ["a", "b"]] = [10, 20] postavlja stupac a na 10 i b na 20 za sve retke koji zadovoljavaju uvjet. Možete predati i drugi DataFrame ili 2D array istog oblika.

Zaključak

Razumijevanje razlike između .loc i .iloc jedan je od onih trenutaka kad Pandas iz "tajanstvene biblioteke" prelazi u "alat koji stvarno kontroliram". .loc koristite za label-based pristup i filtriranje, .iloc za pristup po poziciji. Za skalarne operacije sjetite se .at i .iat, a lančano indeksiranje — izbjegavajte ga kao zaraženu datoteku. Uz dolazak Copy-on-Write semantike u Pandas 2.2, indeksiranje napokon postaje predvidljivije nego ikad. Pravi trenutak da svoje navike uskladite s onim što Pandas radi danas, a ne onim što je radio prije pet godina.

O Autoru Editorial Team

Our team of expert writers and editors.