Skip to content

Commit

Permalink
feat(python): Allow column expressions in DataFrame unnest (#20846)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-beedie authored Jan 23, 2025
1 parent ec1da46 commit aa1b45f
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 19 deletions.
7 changes: 0 additions & 7 deletions crates/polars-python/src/dataframe/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,13 +651,6 @@ impl PyDataFrame {
})
}

pub fn unnest(&self, py: Python, columns: Vec<String>) -> PyResult<Self> {
let df = py
.allow_threads(|| self.df.unnest(columns))
.map_err(PyPolarsErr::from)?;
Ok(df.into())
}

pub fn clear(&self, py: Python) -> Self {
py.allow_threads(|| self.df.clear()).into()
}
Expand Down
3 changes: 1 addition & 2 deletions py-polars/polars/dataframe/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -11261,8 +11261,7 @@ def unnest(
│ bar ┆ 2 ┆ b ┆ null ┆ [3] ┆ womp │
└────────┴─────┴─────┴──────┴───────────┴───────┘
"""
columns = _expand_selectors(self, columns, *more_columns)
return self._from_pydf(self._df.unnest(columns))
return self.lazy().unnest(columns, *more_columns).collect(_eager=True)

def corr(self, **kwargs: Any) -> DataFrame:
"""
Expand Down
20 changes: 10 additions & 10 deletions py-polars/tests/unit/constructors/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from pydantic import BaseModel, Field, TypeAdapter

import polars as pl
import polars.selectors as cs
from polars._utils.construction.utils import try_get_type_hints
from polars.datatypes import numpy_char_code_to_dtype
from polars.dependencies import dataclasses, pydantic
Expand Down Expand Up @@ -1409,24 +1410,23 @@ def test_from_records_nullable_structs() -> None:
assert series.to_list() == []


def test_from_categorical_in_struct_defined_by_schema() -> None:
@pytest.mark.parametrize("unnest_column", ["a", pl.col("a"), cs.by_name("a")])
def test_from_categorical_in_struct_defined_by_schema(unnest_column: Any) -> None:
df = pl.DataFrame(
{
"a": [
{"value": "foo", "counts": 1},
{"value": "bar", "counts": 2},
]
},
{"a": [{"value": "foo", "counts": 1}, {"value": "bar", "counts": 2}]},
schema={"a": pl.Struct({"value": pl.Categorical, "counts": pl.UInt32})},
)

result = df.unnest("a")

expected = pl.DataFrame(
{"value": ["foo", "bar"], "counts": [1, 2]},
schema={"value": pl.Categorical, "counts": pl.UInt32},
)
assert_frame_equal(result, expected, categorical_as_str=True)

res_eager = df.unnest(unnest_column)
assert_frame_equal(res_eager, expected, categorical_as_str=True)

res_lazy = df.lazy().unnest(unnest_column)
assert_frame_equal(res_lazy.collect(), expected, categorical_as_str=True)


def test_nested_schema_construction() -> None:
Expand Down

0 comments on commit aa1b45f

Please sign in to comment.