pola-rs/polars · error
comparing durations with different units is not supported
Error message
comparing durations with different units is not supported
What it means
AnyValue::partial_cmp panics when ordering two Duration scalars with different time units (us/ms/ns). Durations are raw i64 counts in a unit; cross-unit ordering would be wrong without conversion, which this scalar path does not do.
Source
Thrown at crates/polars-core/src/datatypes/any_value.rs:1420
(Float64(l), Float64(r)) => Some(l.tot_cmp(r)),
(String(l), String(r)) => l.partial_cmp(r),
(Binary(l), Binary(r)) => l.partial_cmp(r),
#[cfg(feature = "dtype-date")]
(Date(l), Date(r)) => l.partial_cmp(r),
#[cfg(feature = "dtype-datetime")]
(Datetime(lt, lu, lz), Datetime(rt, ru, rz)) => {
if lu != ru || lz != rz {
unimplemented!(
"comparing datetimes with different units or timezones is not supported"
);
}
lt.partial_cmp(rt)
},
#[cfg(feature = "dtype-duration")]
(Duration(lt, lu), Duration(rt, ru)) => {
if lu != ru {
unimplemented!("comparing durations with different units is not supported");
}
lt.partial_cmp(rt)
},
#[cfg(feature = "dtype-time")]
(Time(l), Time(r)) => l.partial_cmp(r),
#[cfg(feature = "dtype-categorical")]
(Categorical(l_cat, l_map), Categorical(r_cat, r_map)) => unsafe {
let l_str = l_map.cat_to_str_unchecked(*l_cat);
let r_str = r_map.cat_to_str_unchecked(*r_cat);
l_str.partial_cmp(r_str)
},
#[cfg(feature = "dtype-categorical")]
(Enum(l_cat, l_map), Enum(r_cat, r_map)) => {
if !Arc::ptr_eq(l_map, r_map) {
unimplemented!("can't order enums from different FrozenCategories")
}
l_cat.partial_cmp(r_cat)View on GitHub (pinned to df599052da)
Solutions
- Cast duration columns to one unit before comparing: col.dt.cast_time_unit('us') works for durations too, or .cast(pl.Duration('us'))
- Normalize at the source: keep all upstream datetimes in a single time unit so derived durations share it
Example fix
# before
cmp = df1["dur"].get(0) < df2["dur"].get(0) # ms vs us -> panic
# after
d1 = df1["dur"].cast(pl.Duration("us")).get(0)
d2 = df2["dur"].cast(pl.Duration("us")).get(0)
cmp = d1 < d2 Defensive patterns
Strategy: validation
Validate before calling
def durations_comparable(a: pl.Series, b: pl.Series) -> bool:
return (
isinstance(a.dtype, pl.Duration) and isinstance(b.dtype, pl.Duration)
and a.dtype.time_unit == b.dtype.time_unit
) Type guard
def aligned_duration(s: pl.Series, unit: str = "us") -> pl.Series:
return s.cast(pl.Duration(unit)) Prevention
- Derive durations from datetimes kept in a single time unit
- Cast duration columns to one unit before extracting scalars
When it happens
Trigger: Comparing duration AnyValues from columns of different dtypes: Duration('ms') vs Duration('us'), e.g. df1["d"].get(0) < df2["d"].get(0) after diff/subtract operations that produced different units.
Common situations: Durations derived from datetime columns with mismatched units (subtractions of ms vs us timestamps), or comparing parsed durations against literals with a different unit.
Related errors
- comparing datetimes with different units or timezones is not
- can't order enums from different FrozenCategories
- ordering for List dtype is not supported
- ordering for Array dtype is not supported
- ordering for Object dtype is not supported
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/a12b5c38515871b1.
Report an issue: GitHub.