Sahaj.blogs
7 Mar 2024 · StudyPhase 4 · Pandas

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 bylabelsinteger positions
slice a:bincludes bexcludes b
boolean maskyesyes (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 like df[mask]["col"] = value may modify a temporary copy and get lost. Under pandas’ Copy-on-Write it never updates df.
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.9

#pandas#indexing

Sources

  1. Indexing and selecting data — pandas
  2. pandas.DataFrame.query — pandas
  3. Copy-on-Write (CoW) — pandas