Problems / IQR Outliers Within Each Category / Editorial
PERCENTILE_CONT(0.25)
PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY amount)
PERCENTILE_CONT
quantile(0.25)
transactions
category
q1
q3
is_outlier = amount < q1 - 1.5*IQR OR amount > q3 + 1.5*IQR
<=
>=
txn_id
In PySpark/SQLFrame there is no native percentile_cont function object, but F.expr("percentile_cont(0.25) within group (order by amount)") inside .agg() passes the ordered-set aggregate straight through to DuckDB.
percentile_cont
F.expr("percentile_cont(0.25) within group (order by amount)")
.agg()
Outlier detection is only meaningful relative to a peer group: 100 is a wild outlier among dining bills of 5–11 but would be the cheapest row in travel, and travel's genuine outlier (2) sits comfortably inside every other category's fences. The aggregate-then-rejoin pattern is the standard way to compare each row against group-level statistics. The second discipline this problem enforces is boundary semantics: "1.5 × IQR" fences are conventionally inclusive, so outliers are *strictly* outside — an off-by-one in the comparison operator flips exactly one row in this dataset.
travel
Solve IQR Outliers Within Each Category yourself →