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

feat(rust, python): allow unordered struct creating from anyvalues #6321

Merged
merged 1 commit into from
Jan 19, 2023
Merged
Show file tree
Hide file tree
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
41 changes: 25 additions & 16 deletions polars/polars-core/src/series/any_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,25 +125,11 @@ impl Series {
for av in av.iter() {
match av {
AnyValue::StructOwned(payload) => {
// TODO: optimize
let av_fields = &payload.1;
let av_values = &payload.0;

// all fields are available in this single value
// we can use the index to get value
if dtype_fields.len() == av_fields.len() {
for (l, r) in dtype_fields.iter().zip(av_fields.iter()) {
if l.name() != r.name() {
return Err(PolarsError::ComputeError(
"struct orders must remain the same".into(),
));
}
}
let av_val =
av_values.get(i).cloned().unwrap_or(AnyValue::Null);
field_avs.push(av_val)
}
// not all fields are available, we search the proper field
else {
let mut append_by_search = || {
// search for the name
let mut pushed = false;
for (av_fld, av_val) in av_fields.iter().zip(av_values) {
Expand All @@ -156,6 +142,29 @@ impl Series {
if !pushed {
field_avs.push(AnyValue::Null)
}
};

// all fields are available in this single value
// we can use the index to get value
if dtype_fields.len() == av_fields.len() {
let mut search = false;
for (l, r) in dtype_fields.iter().zip(av_fields.iter()) {
if l.name() != r.name() {
search = true;
}
}
if search {
append_by_search()
} else {
let av_val =
av_values.get(i).cloned().unwrap_or(AnyValue::Null);
field_avs.push(av_val)
}
}
// not all fields are available, we search the proper field
else {
// search for the name
append_by_search()
}
}
_ => field_avs.push(AnyValue::Null),
Expand Down
9 changes: 3 additions & 6 deletions py-polars/tests/unit/test_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,12 +457,9 @@ def test_struct_comparison() -> None:


def test_struct_order() -> None:
with pytest.raises(pl.ComputeError, match="struct orders must remain the same"):
pl.DataFrame(
{
"col1": [{"a": 1, "b": 2}, {"b": 4, "a": 3}],
}
)
assert pl.DataFrame({"col1": [{"a": 1, "b": 2}, {"b": 4, "a": 3}],}).to_dict(
False
) == {"col1": [{"a": 1, "b": 2}, {"a": 3, "b": 4}]}

# null values should not trigger this
assert (
Expand Down