Search code examples
pythonpython-polars

Cannot use selector in polars.DataFrame.unpivot()


I cannot use the pl.exclude() selector as index in pl.DataFrame.unpivot despite the documentation of this method type hinting the index parameter as follows.

index: 'ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None' = None

The follow code can be used to reproduce the error.

import polars as pl

df = pl.DataFrame({
    'foo' : ['one', 'two', 'three'],
    'bar' : ['four', 'five', 'six'],
    'baz' : [10, 20, 30],
    'qux' : [50, 60, 70]
})

column_list = ['baz', 'qux']
df.unpivot(column_list, index=pl.exclude(column_list))
TypeError: argument 'index': 'Expr' object cannot be converted to 'PyString'

Moreover, using the columns explicitly works fine.

df.unpivot(column_list, index=['foo', 'bar'])

So, how can column selectors be used in pl.DataFrame.unpivot?


Solution

  • pl.exclude is a "regular" polars expression (of type pl.Expr). Selectors are special objects (also expressions, but of a specific subtype cs._selector_proxy_) that can be found in pl.selectors.

    import polars.selectors as cs
    
    column_list = ['baz', 'qux']
    df.unpivot(column_list, index=cs.exclude(column_list))
    
    shape: (6, 4)
    ┌───────┬──────┬──────────┬───────┐
    │ foo   ┆ bar  ┆ variable ┆ value │
    │ ---   ┆ ---  ┆ ---      ┆ ---   │
    │ str   ┆ str  ┆ str      ┆ i64   │
    ╞═══════╪══════╪══════════╪═══════╡
    │ one   ┆ four ┆ baz      ┆ 10    │
    │ two   ┆ five ┆ baz      ┆ 20    │
    │ three ┆ six  ┆ baz      ┆ 30    │
    │ one   ┆ four ┆ qux      ┆ 50    │
    │ two   ┆ five ┆ qux      ┆ 60    │
    │ three ┆ six  ┆ qux      ┆ 70    │
    └───────┴──────┴──────────┴───────┘