Wide tables need column-wise operations without writing one line per column.
One expression can expand into many. pl.col("a", "b").round(1) applies to both columns; pl.col(pl.Float64) picks every Float64 column; pl.all() picks everything; pl.col("^sales_.*$") picks by regex (the pattern must start with ^ and end with $). pl.all().exclude("id") drops some.
The selectors module, imported as import polars.selectors as cs, is more expressive and composes with set operations:
cs.numeric(),cs.string(),cs.temporal(),cs.boolean()cs.starts_with("sales_"),cs.ends_with("_id"),cs.contains("price"),cs.matches(regex)cs.by_name("a", "b"),cs.first(),cs.last()- combine with
|(union),&(intersection),-(difference) and~(complement)
Expanded outputs keep their original names, so in with_columns they overwrite the inputs. To keep both, rename with the .name namespace: .name.suffix("_z"), .name.prefix(...), .name.map(func).
In Polars 2, combining a selector with pl.col(...) using &, | or ^ is an element-wise boolean operation, not a column selection. Stay within selectors, using cs.by_name(...), when you mean set logic.
cs.expand_selector(df, selector) shows which columns a selector picks, handy for debugging.
Example
import polars as pl
import polars.selectors as cs
df = pl.DataFrame({
"id": [1, 2], "name": ["a", "b"],
"sales_q1": [10.0, 20.0], "sales_q2": [30.0, 10.0], "rate": [0.5, 0.25],
})
print(cs.expand_selector(df, cs.numeric() - cs.by_name("id")))
# ('sales_q1', 'sales_q2', 'rate')
out = df.with_columns(
(cs.starts_with("sales_") / 10).name.suffix("_k"),
pl.col(pl.String).str.to_uppercase(),
)
print(out.columns)
# ['id', 'name', 'sales_q1', 'sales_q2', 'rate', 'sales_q1_k', 'sales_q2_k']
print(out.select(pl.sum_horizontal(cs.ends_with("_k"))).to_series().to_list())
# [4.0, 3.0]Remember
pl.col(dtype),pl.all()and regex names expand into many columnspolars.selectorscompose with|,&,-,~- Use
.name.suffix()to keep originals when transforming many columns
Watch out for
- Forgetting
^...$around a regex inpl.col, so it is read as a plain column name.