Topics in this subject
Pandas 2 min read Updated 4 Aug 2026

5. Selecting Data

df = pd.DataFrame({'age':[25,30,35], 'city':['NYC','LA','SF']},

loc vs iloc (the most-tested topic)#

Accessor Indexes by Endpoint
loc labels inclusive
iloc integer positions exclusive
at single value by label (fast)
iat single value by position (fast)
df = pd.DataFrame({'age':[25,30,35], 'city':['NYC','LA','SF']},
                  index=['a','b','c'])

df.loc['a']              # row by label
df.loc['a':'b']          # label slice INCLUDES 'b'
df.loc['a', 'city']      # 'NYC'
df.loc[df.age > 28]      # boolean filter

df.iloc[0]               # first row
df.iloc[0:2]             # positions 0,1 (EXCLUDES 2)
df.iloc[0, 1]            # 'NYC'

df.at['a', 'city']       # fast scalar access
df.iat[0, 1]             # fast scalar by position

⚠️ Common Mistake: loc slices are inclusive of the end label; iloc slices are exclusive. df.loc['a':'b'] returns rows a AND b.

Boolean filtering, query, isin, between#

df[df['age'] > 28]
df[(df['age'] > 25) & (df['city'] == 'SF')]   # use & | ~, wrap in ()
df.query('age > 28 and city == "SF"')          # readable
df[df['city'].isin(['NYC', 'SF'])]
df[df['age'].between(26, 34)]                   # inclusive both ends

⚠️ Common Mistake: Use &, |, ~ (not and, or, not) for element-wise masks, and wrap each condition in parentheses because & binds tighter than >.

where and mask#

df['age'].where(df['age'] > 30, 0)   # keep where TRUE, else 0
df['age'].mask(df['age'] > 30, 0)    # opposite: replace where TRUE

SettingWithCopyWarning — the #1 Pandas trap ⚠️ 🎯#

Chained indexing (df[...][...]) may operate on a temporary copy, so your write silently does nothing:

# ❌ chained — may set on a throwaway copy, warns, may not persist
df[df.age > 30]['city'] = 'Unknown'

# ✅ single .loc call — selects and assigns in one operation
df.loc[df.age > 30, 'city'] = 'Unknown'

# ✅ if you truly want a separate frame to edit, make the copy explicit
sub = df[df.age > 30].copy()
sub['city'] = 'Unknown'

📌 Rule: one .loc[rows, cols] for a read-modify; call .copy() when you deliberately want an independent slice. Never assign through chained [].

Interview Question: loc vs iloc? loc uses labels (end-inclusive); iloc uses integer positions (end-exclusive). What causes SettingWithCopyWarning? Chained indexing assigning to a possible view/copy — use a single .loc.