Selecting Rows & Columns
Python · Pandas Basics
Theory
pandas has a few selectors, each with one job. df['name'] returns one column as a Series and df[['name', 'amount']] returns several as a DataFrame. .loc selects by label: df.loc[row_labels, column_names], where slices include both ends, so df.loc[1:3, ['name', 'amount']] gives rows labelled 1, 2 and 3. .iloc selects by integer position like a Python list, so slices exclude the end: df.iloc[0:2, [0, 2]] gives the first two rows and the first and third columns.
For a single value use .at[label, col] or .iat[pos, pos], which are faster than loc/iloc. .loc also accepts boolean masks, so df.loc[df['city'] == 'Pune', 'amount'] filters rows and picks a column in one step, and the same form works for assignment: df.loc[mask, 'amount'] = 0. set_index('order_id') turns a column into the row labels so .loc can look rows up by business key.
Why we use it
Clear, explicit selection avoids the classic pandas bugs: off-by-one slices, label and position mixed up, and chained indexing that silently updates a copy instead of your DataFrame.
When to use it
Use [] for columns, .loc for labels and masks, .iloc for positions (first n rows, every other column) and .at/.iat for one cell. To update values always use a single .loc[mask, col] = value, not df[mask]['col'] = value.
How it works
- What do you want to select?
- Only columns? Yes: Use df['col'] or df[['c1', 'c2']]. No: Rows are involved.
- By label or condition? Yes: Use df.loc[rows, cols]. No: Use df.iloc[row_pos, col_pos].
- Just one cell? Yes: Use .at[label, col] or .iat[i, j]. No: Keep the loc/iloc result.
- Selected Series or DataFrame
Syntax
df['col']; df[['c1', 'c2']]
df.loc[row_labels, col_labels]
df.iloc[row_pos, col_pos]
df.at[label, 'col']; df.iat[i, j]Example
print(df.loc[1:3, ['name', 'amount']])
print(df.iloc[0:2, [0, 2]])
print(df.at[2, 'name'])Key points
- .loc slices include the end label; .iloc slices exclude the end position
- df['a'] returns a Series; df[['a']] returns a one-column DataFrame
- Update with df.loc[mask, 'col'] = value, never chained df[mask]['col'] = ...
- .at / .iat are the fastest way to read or set one cell
- SQL equivalent: SELECT name, amount FROM t WHERE ... ; LIMIT n is df.head(n) or df.iloc[:n]