Missing Values
Drop Missing Rows
Remove rows that contain a missing value from a tabular dataset. By hand,
scan parallel lists for None entries and collect only the names whose
score is present. With pandas, DataFrame.dropna() filters out every row
with at least one NaN in a single call.
By hand
Iterate over range(len(names)). Check scores[i] is not None; when the
score is present, append the corresponding name to kept. The trace shows
kept growing only on non-missing rows.
naive.py
Replay: real traced execution (multi-file project)
names = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
scores = [82, None, 91, None, 74]
kept = []
for i in range(len(names)):
if scores[i] is not None:
kept.append(names[i])
print('RESULT:', kept)
names ← ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
1names = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']2scores = [82, None, 91, None, 74]values this step['Alice', 'Bob', 'Carol', 'Dave', 'Eve']namesscores ← [82, None, 91, None, 74]
1names = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']2scores = [82, None, 91, None, 74]3kept = []values this step[82, None, 91, None, 74]scoreskept ← []
2scores = [82, None, 91, None, 74]3kept = []4for i in range(len(names)):values this step[]kepti ← 0
3kept = []4for i in range(len(names)):5 if scores[i] is not None:values this step0iif scores[i] is not None:
4for i in range(len(names)):5 if scores[i] is not None:6 kept.append(names[i])kept ← ['Alice']
5 if scores[i] is not None:6 kept.append(names[i])7print('RESULT:', kept)values this step[] → ['Alice']kepti ← 1
3kept = []4for i in range(len(names)):5 if scores[i] is not None:values this step0 → 1iif scores[i] is not None:
4for i in range(len(names)):5 if scores[i] is not None:6 kept.append(names[i])i ← 2
3kept = []4for i in range(len(names)):5 if scores[i] is not None:values this step1 → 2iif scores[i] is not None:
4for i in range(len(names)):5 if scores[i] is not None:6 kept.append(names[i])kept ← ['Alice', 'Carol']
5 if scores[i] is not None:6 kept.append(names[i])7print('RESULT:', kept)values this step['Alice'] → ['Alice', 'Carol']kepti ← 3
3kept = []4for i in range(len(names)):5 if scores[i] is not None:values this step2 → 3iif scores[i] is not None:
4for i in range(len(names)):5 if scores[i] is not None:6 kept.append(names[i])i ← 4
3kept = []4for i in range(len(names)):5 if scores[i] is not None:values this step3 → 4iif scores[i] is not None:
4for i in range(len(names)):5 if scores[i] is not None:6 kept.append(names[i])kept ← ['Alice', 'Carol', 'Eve']
5 if scores[i] is not None:6 kept.append(names[i])7print('RESULT:', kept)values this step['Alice', 'Carol'] → ['Alice', 'Carol', 'Eve']keptfor i in range(len(names)):
3kept = []4for i in range(len(names)):5 if scores[i] is not None:stdout ← RESULT: ['Alice', 'Carol', 'Eve']
6 kept.append(names[i])7print('RESULT:', kept)values this stepRESULT: ['Alice', 'Carol', 'Eve']stdout
With pandas
Build a DataFrame from the parallel lists — pandas infers float64 for the
numeric column, converting None to NaN. df.dropna() returns a new
DataFrame without any NaN rows. The snapshot shows the shape before and
after so the drop count is immediately visible.
library.py
import pandas as pd
from dalib.display import set_display
set_display()
names = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve']
scores = [82, None, 91, None, 74]
df = pd.DataFrame({'name': names, 'score': scores})
clean = df.dropna()
result = clean['name'].tolist()
print('columns:', df.columns.tolist())
print('shape before:', df.shape)
print('shape after:', clean.shape)
print('RESULT:', result)
columns: ['name', 'score']
shape before: (5, 2)
shape after: (3, 2)
RESULT: ['Alice', 'Carol', 'Eve']
Implementation notes
dropna()drops any row that has at least oneNaNby default (how='any'). Passhow='all'to drop only rows where every cell is missing.subset=['score']limits the check to thescorecolumn, leaving rows with missing values in other columns intact.- The returned DataFrame keeps its original index labels — use
.reset_index (drop=True)after if you need a clean 0-based index. - Cross-reference:
detect-missing(this chapter) for identifying which positions are missing before deciding whether to drop or fill.