narwhals icon indicating copy to clipboard operation
narwhals copied to clipboard

err: improve `Multi-output expressions are not supported in this context` error message

Open MarcoGorelli opened this issue 1 year ago • 2 comments

example of how to get it:

In [1]: import narwhals as nw

In [2]: import pandas as pd

In [3]: nw.from_native(pd.Series([1,2,3]), series_only=True) == [1,2,3]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 1
----> 1 nw.from_native(pd.Series([1,2,3]), series_only=True) == [1,2,3]

File ~/scratch/.venv/lib/python3.12/site-packages/narwhals/series.py:1487, in Series.__eq__(self, other)
   1485 def __eq__(self, other: object) -> Self:  # type: ignore[override]
   1486     return self._from_compliant_series(
-> 1487         self._compliant_series.__eq__(self._extract_native(other))
   1488     )

File ~/scratch/.venv/lib/python3.12/site-packages/narwhals/_pandas_like/series.py:238, in PandasLikeSeries.__eq__(self, other)
    236 def __eq__(self, other: object) -> PandasLikeSeries:  # type: ignore[override]
    237     ser = self._native_series
--> 238     other = validate_column_comparand(self._native_series.index, other)
    239     return self._from_native_series(self._rename(ser.__eq__(other), ser.name))

File ~/scratch/.venv/lib/python3.12/site-packages/narwhals/_pandas_like/utils.py:40, in validate_column_comparand(index, other)
     37     if len(other) > 1:
     38         # e.g. `plx.all() + plx.all()`
     39         msg = "Multi-output expressions are not supported in this context"
---> 40         raise ValueError(msg)
     41     other = other[0]
     42 if isinstance(other, PandasLikeDataFrame):

ValueError: Multi-output expressions are not supported in this context

MarcoGorelli avatar Sep 07 '24 08:09 MarcoGorelli

Should this comparison be supported? Polars allows it if the comparand is of the same length, and panics otherwise.

FBruzzesi avatar Sep 10 '24 21:09 FBruzzesi

not sure tbh, because for pandas_like we share code between expr and series, and polars doesn't allow it for expr

In [3]: df.select(pl.col('a')==[1,1])
---------------------------------------------------------------------------
SchemaError                               Traceback (most recent call last)
Cell In[3], line 1
----> 1 df.select(pl.col('a')==[1,1])

File ~/scratch/.venv/lib/python3.12/site-packages/polars/dataframe/frame.py:8968, in DataFrame.select(self, *exprs, **named_exprs)
   8868 def select(
   8869     self, *exprs: IntoExpr | Iterable[IntoExpr], **named_exprs: IntoExpr
   8870 ) -> DataFrame:
   8871     """
   8872     Select columns from this DataFrame.
   8873
   (...)
   8966     └──────────────┘
   8967     """
-> 8968     return self.lazy().select(*exprs, **named_exprs).collect(_eager=True)

File ~/scratch/.venv/lib/python3.12/site-packages/polars/lazyframe/frame.py:2032, in LazyFrame.collect(self, type_coercion, predicate_pushdown, projection_pushdown, simplify_expression, slice_pushdown, comm_subplan_elim, comm_subexpr_elim, cluster_with_columns, no_optimization, streaming, engine, background, _eager, **_kwargs)
   2030 # Only for testing purposes
   2031 callback = _kwargs.get("post_opt_callback", callback)
-> 2032 return wrap_df(ldf.collect(callback))

SchemaError: could not evaluate comparison between series 'a' of dtype: i64 and series 'literal' of dtype: list[i64]

MarcoGorelli avatar Sep 13 '24 12:09 MarcoGorelli

@MarcoGorelli do we still want this?

DeaMariaLeon avatar Oct 18 '24 08:10 DeaMariaLeon

If it's possible to give a good message, then yes 👍

MarcoGorelli avatar Oct 22 '24 21:10 MarcoGorelli

closed by #1382

MarcoGorelli avatar Nov 15 '24 17:11 MarcoGorelli