pandas loc vs iloc: labels, positions and safe assignment
Use a nonconsecutive integer index to expose label versus position selection, slicing endpoints and aligned assignment.
loc selects pandas rows and columns by label. iloc selects them by integer position. An integer index label is still a label: .loc[20] asks for label 20, while .iloc[2] asks for the third row.
The distinction can stay hidden when a table happens to have the default index 0, 1, 2, .... Our invented inspection table deliberately uses the labels 10, 20 and 40. We will filter rows, assign a corrected value and expose how label alignment affects a second assignment.
Predict the selected records
A label slice through a suitable ordered index includes its final label. A positional slice follows Python's usual stop-exclusive rule. Thus .loc[10:20] contains labels 10 and 20, while .iloc[0:1] contains only the first row.
A Boolean Series supplied to loc is aligned by labels. iloc expects a positional Boolean array rather than a label-bearing Boolean Series. Do not discard the index just to silence an alignment error unless position really is your intended contract.
The program uses a simple one-step loc assignment. It avoids chained selection such as frame[mask]['score'] = value, which does not provide the same direct assignment contract and is especially inappropriate under pandas Copy-on-Write behavior.
import pandas as pd
frame = pd.DataFrame({'part': ['gear', 'bolt', 'shaft'], 'score': [8., 5., 9.]},
index=[10, 20, 40])
print('loc label 20:', frame.loc[20, 'part'])
print('iloc position 2:', frame.iloc[2, 0])
print('loc slice:', frame.loc[10:20].index.tolist())
print('iloc slice:', frame.iloc[0:1].index.tolist())
mask = frame['score'] < 6
frame.loc[mask, 'score'] = 6.
print('corrected scores:', frame['score'].tolist())
try:
frame.loc[1]
except KeyError:
print('label 1: missing')
values = pd.Series([100., 200.], index=[40, 10])
frame.loc[[10, 40], 'score'] = values
print('aligned assignment:', frame['score'].tolist())
assert frame.loc[10, 'score'] == 200
assert frame.loc[40, 'score'] == 100
assert frame.index.is_unique
Checked output:
loc label 20: bolt
iloc position 2: shaft
loc slice: [10, 20]
iloc slice: [10]
corrected scores: [8.0, 6.0, 9.0]
label 1: missing
aligned assignment: [200.0, 6.0, 100.0]
Inspect alignment during assignment
The Series stores 100 under label 40 and 200 under label 10. Assigning it through loc[[10, 40], 'score'] aligns by those labels, producing 200 at row 10 and 100 at row 40. The order in which values appear in the Series is not the assignment order.
If you intentionally want positional assignment, use a positional selection and an array with a checked shape. Converting a Series to an array removes its labels; that can be correct, but it also removes a useful protection against accidentally mismatched records. State why the labels should be ignored.
Our fixture has a unique index. With duplicate labels, a scalar loc key can select multiple rows and may return a different result shape. Check index.is_unique if your program depends on one label identifying exactly one record. Resetting an index is an explicit data-model change, not a universal fix for duplicate observations.
Separate filtering from cleaning
A mask such as score < 6 encodes a rule. In this example the assignment is a demonstrative correction, not a recommendation to overwrite low inspection scores. Real cleaning should preserve the source measurement, record the reason for a correction and avoid manufacturing model targets.
Missing mask values and nullable data types deserve separate tests. Do not assume the same behavior for a NumPy Boolean array, a pandas nullable Boolean Series and a Python list without checking the selection API.
Extend the fixture
Reorder the rows and predict which iloc selection changes while .loc[20] still identifies the bolt. Then add a duplicate label 20 and inspect the returned object. Finally, give the assignment Series an unrelated label and explain the resulting missing value before deciding how to reject the mismatch.
The Data Tools course develops table indexing and cleaning. Continue with aggregation versus transform to see why preserving row alignment matters when adding group-derived features. Check merge relationships before combining independently indexed tables.
References
pandas indexing guide — Label and positional selection, endpoint rules, Boolean indexing and assignment.