pola-rs/polars · error · ValueError
DataFrame columns do not match
Error message
DataFrame columns do not match
What it means
Element-wise comparison of two DataFrames (df1 == df2, !=, <, >, ...) goes through _compare_to_other_df, which first requires identical columns: same names, same order. Since column order changes the positional pairing of the comparison, a mismatch (including mere reordering) raises ValueError instead of comparing wrong pairs.
Source
Thrown at py-polars/src/polars/dataframe/frame.py:1107
return PolarsDataFrame(self, allow_copy=allow_copy)
def _comp(self, other: Any, op: ComparisonOperator) -> DataFrame:
"""Compare a DataFrame with another object."""
if isinstance(other, DataFrame):
return self._compare_to_other_df(other, op)
else:
return self._compare_to_non_df(other, op)
def _compare_to_other_df(
self,
other: DataFrame,
op: ComparisonOperator,
) -> DataFrame:
"""Compare a DataFrame with another DataFrame."""
if self.columns != other.columns:
msg = "DataFrame columns do not match"
raise ValueError(msg)
if self.shape != other.shape:
msg = "DataFrame dimensions do not match"
raise ValueError(msg)
suffix = "__POLARS_CMP_OTHER"
other_renamed = other.select(F.all().name.suffix(suffix))
combined = F.concat([self, other_renamed], how="horizontal", strict=True)
if op == "eq":
expr = [F.col(n) == F.col(f"{n}{suffix}") for n in self.columns]
elif op == "neq":
expr = [F.col(n) != F.col(f"{n}{suffix}") for n in self.columns]
elif op == "gt":
expr = [F.col(n) > F.col(f"{n}{suffix}") for n in self.columns]
elif op == "lt":
expr = [F.col(n) < F.col(f"{n}{suffix}") for n in self.columns]
elif op == "gt_eq":
expr = [F.col(n) >= F.col(f"{n}{suffix}") for n in self.columns]View on GitHub (pinned to df599052da)
Solutions
- Align first: df2 = df2.select(df1.columns) then compare
- Rename mismatched columns before comparing: df2 = df2.rename({'old': 'new'})
- For order-insensitive equality testing use df1.equals(df2) or assert_frame_equal(left, right, check_column_order=False)
- For exact equality semantics use df1.equals(df2) which also checks dtypes
Example fix
# before result = df1 == df2.select(['b', 'a']) # ValueError # after df2 = df2.select(df1.columns) result = df1 == df2
Defensive patterns
Strategy: validation
Validate before calling
if list(df.columns) != list(other.columns):
other = other.select(df.columns) # reorder/project to match
assert list(df.columns) == list(other.columns)
result = df == other Prevention
- Normalize column order with other.select(df.columns) before element-wise comparison
- Use polars.testing.assert_frame_equal(check_column_order=False) in tests instead of == checks
- Watch for column reordering after select/join operations in pipelines
When it happens
Trigger: df1 == df2 after df2 was built with a different column order or renamed columns; comparing a df to a filtered/selected version (df2 = df[['b', 'a']]); comparing against a join result whose column order differs.
Common situations: Test assertions comparing expected vs actual frames where construction order drifted; comparing a df to its sorted-by-column version; pipelines where one side passed through a select/rename.
Related errors
- DataFrame dimensions do not match
- data does not match the number of columns
- dimensions of columns arg ({len(columns)}) must match data d
- selecting rows by passing a boolean mask to `__getitem__` is
- DataFrame constructor called with unsupported type {type(dat
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/aabf73be77449e68.
Report an issue: GitHub.