pola-rs/polars · error
comparing categoricals with different Categories is not…
Error message
comparing categoricals with different Categories is not supported through AnyValue
What it means
AnyValue::eq_missing refuses to compare two Categorical values whose category mappings are different Arc allocations (Arc::ptr_eq fails). The Hash impl for AnyValue hashes the raw physical index, so comparing values from different Categories/mappings would give wrong equality results. Instead of silently returning a wrong answer, the method panics via unimplemented!().
Solutions
- Cast one or both columns to a common mapping before comparing: `col.cast(DataType::Categorical(None, CategoricalOrdering::default()))` or use `.to_physical()` (u32) comparison
- Use the global string cache (pl.StringCache() / set_string_cache) so all categoricals share one rev-map
- Compare the underlying string representations instead (cast to Utf8/Str before the comparison)
- Restructure the operation to avoid cross-Series AnyValue comparison, e.g. compare via join on string keys
Example fix
// before: comparing categoricals from two independently built Series
let a = Series::new("a", ["x", "y"]).unwrap().cast(&DataType::Categorical(None, Default::default())).unwrap();
let b = Series::new("b", ["x", "z"]).unwrap().cast(&DataType::Categorical(None, Default::default())).unwrap();
let _ = a.equal(&b)?; // may hit the unimplemented!() via AnyValue comparisons
// after: share a mapping via the global string cache
let _guard = polars::datatypes::PlStringRefCache::insert();
let a = Series::new("a", ["x", "y"]).unwrap().cast(&DataType::Categorical(None, Default::default())).unwrap();
let b = Series::new("b", ["x", "z"]).unwrap().cast(&DataType::Categorical(None, Default::default())).unwrap();
let _ = a.equal(&b)?; Defensive patterns
Strategy: validation
Validate before calling
fn same_categorical_mapping(a: &AnyValue, b: &AnyValue) -> bool {
match (a, b) {
(AnyValue::Categorical(_, l), AnyValue::Categorical(_, r)) => Arc::ptr_eq(l, r),
_ => false,
}
}
// call eq_missing only if same_categorical_mapping(&x, &y) Prevention
- Enable the global string cache when working with multiple categorical columns/frames
- Prefer expression-level comparisons over raw AnyValue comparison
- Cast to physical u32 or Str before cross-frame comparisons
- Check Arc::ptr_eq / dtype metadata equality before comparing categorical values
When it happens
Trigger: Calling AnyValue::eq_missing (directly or via AnyValue::eq / tot_eq) with two AnyValue::Categorical variants built from different CategoricalRevMapping instances — e.g. categorical values taken from two separate DataFrames/Series that each created their own category mapping, or mixing a global mapping with a local one.
Common situations: Joining or comparing columns of dtype Categorical that were constructed independently (each Series gets its own rev-map), concatenating categorical frames, or hand-assembling AnyValues from different Series in expression predicates and filter/when-then contexts.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- can not get dtype of Categorical AnyValue
- comparing enums with different FrozenCategories is not…
- activate dtype-categorical to convert dictionary arrays
- can not get dtype of Enum AnyValue
- can't order enums from different FrozenCategories
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/042bf1203e38ff3e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-core/src/datatypes/any_value.rs:1283
(String(l), String(r)) => l == r,
(Binary(l), Binary(r)) => l == r,
#[cfg(feature = "dtype-time")]
(Time(l), Time(r)) => *l == *r,
#[cfg(all(feature = "dtype-datetime", feature = "dtype-date"))]
(Date(l), Date(r)) => *l == *r,
#[cfg(all(feature = "dtype-datetime", feature = "dtype-date"))]
(Datetime(l, tul, tzl), Datetime(r, tur, tzr)) => {
*l == *r && *tul == *tur && tzl == tzr
},
(List(l), List(r)) => l == r,
#[cfg(feature = "dtype-map")]
(Map(l), Map(r)) => l == r,
#[cfg(feature = "dtype-categorical")]
(Categorical(cat_l, map_l), Categorical(cat_r, map_r)) => {
if !Arc::ptr_eq(map_l, map_r) {
// We can't support this because our Hash impl directly hashes the index. If you
// add support for this we must change the Hash impl.
unimplemented!(
"comparing categoricals with different Categories is not supported through AnyValue"
);
}
cat_l == cat_r
},
#[cfg(feature = "dtype-categorical")]
(Enum(cat_l, map_l), Enum(cat_r, map_r)) => {
if !Arc::ptr_eq(map_l, map_r) {
// We can't support this because our Hash impl directly hashes the index. If you
// add support for this we must change the Hash impl.
unimplemented!(
"comparing enums with different FrozenCategories is not supported through AnyValue"
);
}
cat_l == cat_r
},View on GitHub (pinned to fe841f959e)