Skip to content

Commit

Permalink
use anyvalue if first apply list result is empty (#3480)
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed May 23, 2022
1 parent 8575195 commit 357d427
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
15 changes: 12 additions & 3 deletions py-polars/src/apply/series.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;
use crate::conversion::slice_to_wrapped;
use crate::py_modules::SERIES;
use crate::series::PySeries;
use crate::{PyPolarsErr, Wrap};
use polars::chunked_array::builder::get_list_builder;
Expand Down Expand Up @@ -43,10 +44,18 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>(
.apply_lambda_with_list_out_type(py, lambda.to_object(py), null_count, &series, dt)
.map(|ca| ca.into_series().into())
} else if out.is_instance_of::<PyList>().unwrap() {
let pypolars = PyModule::import(py, "polars").unwrap().to_object(py);
let series = pypolars.getattr(py, "Series").unwrap().call1(py, (out,))?;
let series = SERIES.call1(py, (out,))?;
let py_pyseries = series.getattr(py, "_s").unwrap();
let series = py_pyseries.extract::<PySeries>(py).unwrap().series;

// empty dtype is incorrect use anyvalues.
if series.is_empty() {
let av = out.extract::<Wrap<AnyValue>>()?;
return applyer
.apply_extract_any_values(py, lambda, null_count, av.0)
.map(|s| s.into());
}

let dt = series.dtype();

// make a new python function that is:
Expand All @@ -57,7 +66,7 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>(
move |args, _kwargs| {
Python::with_gil(|py| {
let out = lambda_owned.call1(py, args)?;
pypolars.getattr(py, "Series").unwrap().call1(py, (out,))
SERIES.call1(py, (out,))
})
},
py,
Expand Down
8 changes: 8 additions & 0 deletions py-polars/tests/test_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,11 @@ def test_apply_list_anyvalue_fallback() -> None:
assert df.select(pl.col("text").apply(json.loads)).to_dict(False) == {
"text": [[{"x": 1, "y": 2}, {"x": 3, "y": 4}]]
}

# starts with empty list '[]'
df = pl.DataFrame(
{"text": ["[]", '[{"x": 1, "y": 2}, {"x": 3, "y": 4}]', '[{"x": 1, "y": 2}]']}
)
assert df.select(pl.col("text").apply(json.loads)).to_dict(False) == {
"text": [[], [{"x": 1, "y": 2}, {"x": 3, "y": 4}], [{"x": 1, "y": 2}]]
}

0 comments on commit 357d427

Please sign in to comment.