Selecting and Filtering
Filter by Condition
Build a boolean mask by testing each record's score field in a loop, then keep only the rows where the mask is True. With pandas, a single comparison on a column produces a boolean Series, and indexing a DataFrame with it returns the matching rows in one step.
By hand
Loop over records to build mask (one bool per row). Loop over indices to
collect names where mask[i] is True.
naive.py
Replay: real traced execution (multi-file project)
# trace: ignore records
records = [
{'name': 'al', 'score': 55},
{'name': 'bo', 'score': 82},
{'name': 'cy', 'score': 71},
{'name': 'di', 'score': 90},
]
k = 70
mask = []
for r in records:
mask.append(r['score'] >= k)
names = []
for i in range(len(records)):
if mask[i]:
names.append(records[i]['name'])
print('RESULT:', names)
{'name': 'al', 'score': 55},
2records = [3 {'name': 'al', 'score': 55},4 {'name': 'bo', 'score': 82},{'name': 'bo', 'score': 82},
3{'name': 'al', 'score': 55},4{'name': 'bo', 'score': 82},5{'name': 'cy', 'score': 71},{'name': 'cy', 'score': 71},
4{'name': 'bo', 'score': 82},5{'name': 'cy', 'score': 71},6{'name': 'di', 'score': 90},{'name': 'di', 'score': 90},
5 {'name': 'cy', 'score': 71},6 {'name': 'di', 'score': 90},7]records = [
1# trace: ignore records2records = [3 {'name': 'al', 'score': 55},k ← 70
7]8k = 709mask = []values this step70kmask ← []
8k = 709mask = []10for r in records:values this step[]maskr ← {'name': 'al', 'score': 55}
9mask = []10for r in records:11 mask.append(r['score'] >= k)values this step{'name': 'al', 'score': 55}rmask ← [False]
10for r in records:11 mask.append(r['score'] >= k)12names = []values this step[] → [False]maskr ← {'name': 'bo', 'score': 82}
9mask = []10for r in records:11 mask.append(r['score'] >= k)values this step{'name': 'al', 'score': 55} → {'name': 'bo', 'score': 82}rmask ← [False, True]
10for r in records:11 mask.append(r['score'] >= k)12names = []values this step[False] → [False, True]maskr ← {'name': 'cy', 'score': 71}
9mask = []10for r in records:11 mask.append(r['score'] >= k)values this step{'name': 'bo', 'score': 82} → {'name': 'cy', 'score': 71}rmask ← [False, True, True]
10for r in records:11 mask.append(r['score'] >= k)12names = []values this step[False, True] → [False, True, True]maskr ← {'name': 'di', 'score': 90}
9mask = []10for r in records:11 mask.append(r['score'] >= k)values this step{'name': 'cy', 'score': 71} → {'name': 'di', 'score': 90}rmask ← [False, True, True, True]
10for r in records:11 mask.append(r['score'] >= k)12names = []values this step[False, True, True] → [False, True, True, True]maskfor r in records:
9mask = []10for r in records:11 mask.append(r['score'] >= k)names ← []
11 mask.append(r['score'] >= k)12names = []13for i in range(len(records)):values this step[]namesi ← 0
12names = []13for i in range(len(records)):14 if mask[i]:values this step0iif mask[i]:
13for i in range(len(records)):14 if mask[i]:15 names.append(records[i]['name'])i ← 1
12names = []13for i in range(len(records)):14 if mask[i]:values this step0 → 1iif mask[i]:
13for i in range(len(records)):14 if mask[i]:15 names.append(records[i]['name'])names ← ['bo']
14 if mask[i]:15 names.append(records[i]['name'])16print('RESULT:', names)values this step[] → ['bo']namesi ← 2
12names = []13for i in range(len(records)):14 if mask[i]:values this step1 → 2iif mask[i]:
13for i in range(len(records)):14 if mask[i]:15 names.append(records[i]['name'])names ← ['bo', 'cy']
14 if mask[i]:15 names.append(records[i]['name'])16print('RESULT:', names)values this step['bo'] → ['bo', 'cy']namesi ← 3
12names = []13for i in range(len(records)):14 if mask[i]:values this step2 → 3iif mask[i]:
13for i in range(len(records)):14 if mask[i]:15 names.append(records[i]['name'])names ← ['bo', 'cy', 'di']
14 if mask[i]:15 names.append(records[i]['name'])16print('RESULT:', names)values this step['bo', 'cy'] → ['bo', 'cy', 'di']namesfor i in range(len(records)):
12names = []13for i in range(len(records)):14 if mask[i]:stdout ← RESULT: ['bo', 'cy', 'di']
15 names.append(records[i]['name'])16print('RESULT:', names)values this stepRESULT: ['bo', 'cy', 'di']stdout
With pandas
df['score'] >= k produces a boolean Series. df[mask] keeps only the rows
where the Series is True and returns a sub-DataFrame.
library.py
import pandas as pd
from dalib.display import set_display
set_display()
records = [
{'name': 'al', 'score': 55},
{'name': 'bo', 'score': 82},
{'name': 'cy', 'score': 71},
{'name': 'di', 'score': 90},
]
k = 70
df = pd.DataFrame(records)
mask = df['score'] >= k
filtered = df[mask]
print('mask:', mask.tolist())
print('names:', filtered['name'].tolist())
print('shape:', filtered.shape)
print('RESULT:', filtered['name'].tolist())
mask: [False, True, True, True]
names: ['bo', 'cy', 'di']
shape: (3, 2)
RESULT: ['bo', 'cy', 'di']
Implementation notes
- A boolean Series used as a row index is called boolean indexing. The Series must have the same index as the DataFrame; pandas aligns on labels before filtering.
- The filtered result preserves the original integer index of matching rows
(bo=1, cy=2, di=3 here). Use
.reset_index(drop=True)afterward if you need a fresh 0-based index. df['score'] >= kis vectorized — no Python loop over values. Pandas applies the comparison to the underlying numpy array directly (seemask-from-thresholdin python-numpy ch06).- Cross-reference:
filter-with-mask(python-numpy ch06) for the array version;filter-by-threshold(python-data-basics) for the pure-Python version.