Skip to content

Commit

Permalink
fix: Fix melt panic when there are no value vars (#14057)
Browse files Browse the repository at this point in the history
  • Loading branch information
stinodego committed Jan 29, 2024
1 parent 89a30fc commit ae907fb
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
16 changes: 14 additions & 2 deletions crates/polars-core/src/frame/explode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,25 @@ impl DataFrame {
let id_vars = args.id_vars;
let mut value_vars = args.value_vars;

let value_name = args.value_name.as_deref().unwrap_or("value");
let variable_name = args.variable_name.as_deref().unwrap_or("variable");
let value_name = args.value_name.as_deref().unwrap_or("value");

let len = self.height();

// if value vars is empty we take all columns that are not in id_vars.
if value_vars.is_empty() {
// return empty frame if there are no columns available to use as value vars
if id_vars.len() == self.width() {
let variable_col = Series::new_empty(variable_name, &DataType::String);
let value_col = Series::new_empty(variable_name, &DataType::Null);

let mut out = self.select(id_vars).unwrap().clear().columns;
out.push(variable_col);
out.push(value_col);

return Ok(DataFrame::new_no_checks(out));
}

let id_vars_set = PlHashSet::from_iter(id_vars.iter().map(|s| s.as_str()));
value_vars = self
.get_columns()
Expand Down Expand Up @@ -325,7 +337,7 @@ impl DataFrame {

let variable_col = variable_col.as_box();
// Safety
// The give dtype is correct
// The given dtype is correct
let variables = unsafe {
Series::from_chunks_and_dtype_unchecked(
variable_name,
Expand Down
14 changes: 4 additions & 10 deletions crates/polars-plan/src/logical_plan/builder_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,23 @@ pub(super) fn det_melt_schema(args: &MeltArgs, input_schema: &Schema) -> SchemaR
new_schema.with_column(variable_name, DataType::String);

// We need to determine the supertype of all value columns.
let mut st = None;
let mut supertype = DataType::Null;

// take all columns that are not in `id_vars` as `value_var`
if args.value_vars.is_empty() {
let id_vars = PlHashSet::from_iter(&args.id_vars);
for (name, dtype) in input_schema.iter() {
if !id_vars.contains(name) {
match &st {
None => st = Some(dtype.clone()),
Some(st_) => st = Some(try_get_supertype(st_, dtype).unwrap()),
}
supertype = try_get_supertype(&supertype, dtype).unwrap();
}
}
} else {
for name in &args.value_vars {
let dtype = input_schema.get(name).unwrap();
match &st {
None => st = Some(dtype.clone()),
Some(st_) => st = Some(try_get_supertype(st_, dtype).unwrap()),
}
supertype = try_get_supertype(&supertype, dtype).unwrap();
}
}
new_schema.with_column(value_name, st.unwrap());
new_schema.with_column(value_name, supertype);
Arc::new(new_schema)
}

Expand Down
12 changes: 12 additions & 0 deletions py-polars/tests/unit/operations/test_melt.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,15 @@ def test_melt_projection_pd_7747() -> None:
}
)
assert_frame_equal(result, expected)


# https://github.com/pola-rs/polars/issues/10075
def test_melt_no_value_vars() -> None:
lf = pl.LazyFrame({"a": [1, 2, 3]})

result = lf.melt("a")

expected = pl.LazyFrame(
schema={"a": pl.Int64, "variable": pl.String, "value": pl.Null}
)
assert_frame_equal(result, expected)

0 comments on commit ae907fb

Please sign in to comment.