Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Use correct column names when there are no value columns in unpivot #18340

Merged
merged 1 commit into from
Aug 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion crates/polars-ops/src/frame/pivot/unpivot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ pub trait UnpivotDF: IntoDf {
// return empty frame if there are no columns available to use as value vars
if index.len() == self_.width() {
let variable_col = Series::new_empty(variable_name, &DataType::String);
let value_col = Series::new_empty(variable_name, &DataType::Null);
let value_col = Series::new_empty(value_name, &DataType::Null);

let mut out = self_.select(index).unwrap().clear().take_columns();
out.push(variable_col);
Expand Down Expand Up @@ -193,6 +193,7 @@ impl UnpivotDF for DataFrame {}
#[cfg(test)]
mod test {
use polars_core::df;
use polars_core::utils::Container;

use super::*;

Expand All @@ -205,19 +206,39 @@ mod test {
)
.unwrap();

// Specify on and index
let unpivoted = df.unpivot(["C", "D"], ["A", "B"])?;
assert_eq!(
unpivoted.get_column_names(),
&["A", "B", "variable", "value"]
);
assert_eq!(
Vec::from(unpivoted.column("value")?.i32()?),
&[Some(10), Some(11), Some(12), Some(2), Some(4), Some(6)]
);

// Specify custom column names
let args = UnpivotArgsIR {
on: vec!["C".into(), "D".into()],
index: vec!["A".into(), "B".into()],
variable_name: Some("custom_variable".into()),
value_name: Some("custom_value".into()),
};
let unpivoted = df.unpivot2(args).unwrap();
assert_eq!(
unpivoted.get_column_names(),
&["A", "B", "custom_variable", "custom_value"]
);

// Specify neither on nor index
let args = UnpivotArgsIR {
on: vec![],
index: vec![],
..Default::default()
};

let unpivoted = df.unpivot2(args).unwrap();
assert_eq!(unpivoted.get_column_names(), &["variable", "value"]);
let value = unpivoted.column("value")?;
// String because of supertype
let value = value.str()?;
Expand All @@ -227,13 +248,15 @@ mod test {
&["a", "b", "a", "1", "3", "5", "10", "11", "12", "2", "4", "6"]
);

// Specify index but not on
let args = UnpivotArgsIR {
on: vec![],
index: vec!["A".into()],
..Default::default()
};

let unpivoted = df.unpivot2(args).unwrap();
assert_eq!(unpivoted.get_column_names(), &["A", "variable", "value"]);
let value = unpivoted.column("value")?;
let value = value.i32()?;
let value = value.into_no_null_iter().collect::<Vec<_>>();
Expand All @@ -243,6 +266,20 @@ mod test {
let variable = variable.into_no_null_iter().collect::<Vec<_>>();
assert_eq!(variable, &["B", "B", "B", "C", "C", "C", "D", "D", "D"]);
assert!(unpivoted.column("A").is_ok());

// Specify all columns in index
let args = UnpivotArgsIR {
on: vec![],
index: vec!["A".into(), "B".into(), "C".into(), "D".into()],
..Default::default()
};
let unpivoted = df.unpivot2(args).unwrap();
assert_eq!(
unpivoted.get_column_names(),
&["A", "B", "C", "D", "variable", "value"]
);
assert_eq!(unpivoted.len(), 0);

Ok(())
}
}