Skip to main content

Expr Expressions

Expr is a lazy, composable column expression built from pl.col(name) or pl.lit(value), evaluated in DataFrame's select / with_columns / filter and GroupBy.agg.

pl.col("amount") # reference a column
pl.col("amount") * 1.1 # arithmetic yields a new expression
pl.col("amount").sum().alias("total") # aggregate and rename

:::warning Comparison returns Expr Unlike normal Python semantics, comparison operators on Expr build a lazy boolean expression node and return Expr, NOT bool. So pl.col("a") > 5 is an expression that can be used directly in filter. :::

General Methods

MethodDescription
e.alias(name)Rename the output column of this expression
e.cast(dtype)Cast the result to another dtype
e.is_null() / e.is_not_null()Whether each value is null / non-null
e.fill_null(value)Replace null with an expression or scalar
e.is_in(values)Whether each value is a member of values
e.abs()Element-wise absolute value
e.round(ndigits=0)Round to ndigits decimal places

Aggregation Methods

When used in GroupBy.agg or evaluated over the entire column, these reduce a column to a single value:

MethodDescription
e.sum()Sum of non-null values
e.mean()Arithmetic mean
e.min() / e.max()Minimum / maximum value
e.median()Median
e.std() / e.var()Sample standard deviation / variance
e.count()Count of non-null values
e.n_unique()Count of distinct values
e.first() / e.last()First / last value
e.skew(bias=True)Sample skewness
e.kurtosis(fisher=True, bias=True)Kurtosis (fisher=True for excess kurtosis)
e.mode()Most frequently occurring value(s)
e.quantile(q, interpolation="nearest")Value at the given quantile ("nearest" only)

Rolling Windows

Fixed-size sliding window calculations evaluated in select / with_columns / agg:

MethodDescription
e.rolling_min(window_size, *, min_samples, center)Rolling minimum
e.rolling_max(window_size, *, min_samples, center)Rolling maximum
e.rolling_sum(window_size, *, min_samples, center)Rolling sum
e.rolling_mean(window_size, *, min_samples, center)Rolling mean
e.rolling_median(window_size, *, min_samples, center)Rolling median
e.rolling_std(window_size, *, min_samples, center, ddof=1)Rolling std
e.rolling_var(window_size, *, min_samples, center, ddof=1)Rolling variance
e.rolling_skew(window_size, *, bias, min_samples, center)Rolling skewness
e.rolling_kurtosis(window_size, *, fisher, bias, min_samples, center)Rolling kurtosis
e.rolling_quantile(q, window_size=2, *, min_samples, center)Rolling quantile
e.rolling_map(function, window_size, *, min_samples, center)Apply function(Series) per window

Rolling By (Indexed Windows)

Variable-length windows based on by (a column name or expression, assumed sorted ascending), defined by duration strings:

MethodDescription
e.rolling_min_by(by, window, *, min_samples, closed)Rolling minimum by index
e.rolling_max_by(by, window, *, min_samples, closed)Rolling maximum by index
e.rolling_sum_by(by, window, *, min_samples, closed)Rolling sum by index
e.rolling_mean_by(by, window, *, min_samples, closed)Rolling mean by index
e.rolling_median_by(by, window, *, min_samples, closed)Rolling median by index
e.rolling_std_by(by, window, *, min_samples, closed, ddof=1)Rolling std by index
e.rolling_var_by(by, window, *, min_samples, closed, ddof=1)Rolling variance by index

Exponentially Weighted Moving (EWM)

Provide exactly one of com / span / half_life / alpha:

MethodDescription
e.ewm_mean(*, com/span/half_life/alpha, adjust, min_samples, ignore_nulls)EWM average
e.ewm_sum(*, same params)EWM sum
e.ewm_var(*, same params, bias=False)EWM variance
e.ewm_std(*, same params, bias=False)EWM std

Transformations & Sorting

MethodDescription
e.diff(n=1)Difference from value n positions before
e.cum_sum(*, reverse=False)Cumulative sum
e.cum_prod(*, reverse=False)Cumulative product
e.pct_change(n=1)Percentage change, returns Float64
e.sort(*, descending=False, nulls_last=False)Sort by value (stable)
e.forward_fill(limit=None)Fill nulls with previous non-null value
e.backward_fill(limit=None)Fill nulls with next non-null value
e.unique(*, maintain_order=False)Distinct values
e.shift(n=1, *, fill_value)Shift by n positions; vacated → fill_value
e.interpolate(method="linear")Linear interpolation for nulls ("linear" only)
e.top_k(k=5)k largest values
e.bottom_k(k=5)k smallest values
e.replace_strict(old, new, *, default, return_dtype)Strict value replacement

Window Function over

e.over(*partition_by) -> Expr

Evaluates per partition (grouped by partition_by columns/expressions), then broadcasts each group's result back to the original rows.

# Each row's proportion of its category total
df.with_columns(
(pl.col("amount") / pl.col("amount").sum().over("category")).alias("pct_of_category")
)

Element-wise Mapping map_elements

e.map_elements(function, return_dtype=None, skip_nulls=True) -> Expr

Applies a Python callback to each element. skip_nulls=True (default) skips calling the callback on null elements. return_dtype is inferred when not given.

df.with_columns(
pl.col("score").map_elements(lambda x: "A" if x >= 90 else "B").alias("grade")
)

Conditional Expressions pl.when

pl.when(*predicates)When.then(value)Then.when(...) / .otherwise(value) / .alias(name)

# when/then/otherwise builds a conditional column
df.with_columns(
pl.when(pl.col("amount") > 100).then(pl.lit("high"))
.when(pl.col("amount") > 50).then(pl.lit("mid"))
.otherwise(pl.lit("low"))
.alias("level")
)

# Without .otherwise(), unmatched rows are null
df.with_columns(
pl.when(pl.col("amount") > 100).then(pl.lit("flagged")).alias("flag")
)

Operators

  • Arithmetic: + - * / // % **, and unary - (negate)
  • Comparison: == != < <= > >= (build boolean expressions)
  • Logical: & | ~

String Namespace .str

Access string operations via e.str (available on Expr only, not Series):

MethodDescription
.str.contains(pat)Whether string contains pat
.str.starts_with(pat) / .str.ends_with(pat)Whether string starts / ends with pat
.str.to_uppercase() / .str.to_lowercase()Uppercase / lowercase
.str.strip_chars(chars=None)Strip leading/trailing whitespace, or given chars
.str.replace(old, new)Replace first match
.str.replace_all(old, new)Replace all matches
.str.len_chars()Number of characters
.str.slice(offset, length=None)Slice length characters starting at offset
.str.to_datetime(format=None)Parse to Datetime, optionally with explicit format
.str.to_date(format=None)Parse to Date, optionally with explicit format
# Convert SQL string timestamp column to Datetime, then extract year
df.with_columns(
pl.col("created_at").str.to_datetime().dt.year().alias("year")
)

Datetime Namespace .dt

Access datetime/date operations via e.dt (available on Expr only):

MethodDescription
.dt.year() / .dt.month() / .dt.day()Extract year / month / day
.dt.hour() / .dt.minute() / .dt.second()Extract hour / minute / second
.dt.weekday()ISO weekday number
.dt.truncate(every)Truncate to time bucket boundary (e.g. "1mo", "1d")
.dt.strftime(format)Format as string using strftime-style format
# Monthly aggregation
df.group_by(pl.col("created_at").dt.truncate("1mo").alias("month")).agg(
pl.col("amount").sum().alias("total")
)