Pandas · Selection with loc and iloc
Label-based loc versus position-based iloc, boolean filtering, query(), and avoiding chained assignment.
df.loc[...] | df.iloc[...] | |
|---|---|---|
| selects by | labels | integer positions |
slice a:b | includes b | excludes b |
| boolean mask | yes | yes (as an array) |
df["col"]gives one column (a Series).df[["a", "b"]]gives a DataFrame.- Filter rows with a mask:
df[df.cgpa > 8].df.query("cgpa > 8 and branch == 'ICT'")reads well too. - To assign, use a single
df.loc[mask, "col"] = value. Chained indexing likedf[mask]["col"] = valuemay modify a temporary copy and get lost. Under pandas’ Copy-on-Write it never updatesdf.
import pandas as pd
df = pd.DataFrame(
{"branch": ["CSE", "ICT", "ICT", "ME", "ICT"], "cgpa": [8.4, 7.1, 8.9, 6.8, 9.2]},
index=["Asha", "Ravi", "Sahaj", "Meet", "Dev"],
)
print(df.loc["Ravi":"Meet"]) # label slice: includes Meet
print(df.iloc[1:3]) # position slice: excludes 3
print(df.loc[df.cgpa > 8, "branch"])
print(df.query("branch == 'ICT' and cgpa > 8"))
df.loc[df.cgpa >= 9, "honours"] = True
df["honours"] = df["honours"].fillna(False).astype(bool)
print(df)
print(df.iloc[-1, 0], df.at["Sahaj", "cgpa"])
Output:
branch cgpa
Ravi ICT 7.1
Sahaj ICT 8.9
Meet ME 6.8
branch cgpa
Ravi ICT 7.1
Sahaj ICT 8.9
Asha CSE
Sahaj ICT
Dev ICT
Name: branch, dtype: str
branch cgpa
Sahaj ICT 8.9
Dev ICT 9.2
branch cgpa honours
Asha CSE 8.4 False
Ravi ICT 7.1 False
Sahaj ICT 8.9 False
Meet ME 6.8 False
Dev ICT 9.2 True
ICT 8.9Sources
- Indexing and selecting data — pandas
- pandas.DataFrame.query — pandas
- Copy-on-Write (CoW) — pandas