loc and ilocBoth select data. That's why beginners mix them up.
The simplest way to remember is:
loc → labelsiloc → positionsdf.loc[5]
means:
Give me the row whose label is 5.
On the other hand:
df.iloc[5]
means:
Give me the 6th row.
Those are not necessarily the same row. Especially after filtering.
If your DataFrame index looks like:
0
1
4
7
9
then:
df.iloc[2]
returns the row at position 2. That's index label 4.
This tiny distinction causes a surprising number of bugs.

