polars-df 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/Cargo.lock +595 -709
  4. data/Cargo.toml +1 -0
  5. data/README.md +11 -9
  6. data/ext/polars/Cargo.toml +18 -10
  7. data/ext/polars/src/batched_csv.rs +26 -26
  8. data/ext/polars/src/conversion.rs +272 -136
  9. data/ext/polars/src/dataframe.rs +135 -94
  10. data/ext/polars/src/error.rs +8 -5
  11. data/ext/polars/src/expr/array.rs +15 -0
  12. data/ext/polars/src/expr/binary.rs +18 -6
  13. data/ext/polars/src/expr/datetime.rs +10 -12
  14. data/ext/polars/src/expr/general.rs +78 -264
  15. data/ext/polars/src/expr/list.rs +41 -28
  16. data/ext/polars/src/{expr.rs → expr/mod.rs} +5 -2
  17. data/ext/polars/src/expr/name.rs +44 -0
  18. data/ext/polars/src/expr/rolling.rs +196 -0
  19. data/ext/polars/src/expr/string.rs +94 -66
  20. data/ext/polars/src/file.rs +3 -3
  21. data/ext/polars/src/functions/aggregation.rs +35 -0
  22. data/ext/polars/src/functions/eager.rs +7 -31
  23. data/ext/polars/src/functions/io.rs +10 -10
  24. data/ext/polars/src/functions/lazy.rs +119 -54
  25. data/ext/polars/src/functions/meta.rs +30 -0
  26. data/ext/polars/src/functions/misc.rs +8 -0
  27. data/ext/polars/src/functions/mod.rs +5 -0
  28. data/ext/polars/src/functions/random.rs +6 -0
  29. data/ext/polars/src/functions/range.rs +46 -0
  30. data/ext/polars/src/functions/string_cache.rs +11 -0
  31. data/ext/polars/src/functions/whenthen.rs +7 -7
  32. data/ext/polars/src/lazyframe.rs +61 -44
  33. data/ext/polars/src/lib.rs +173 -84
  34. data/ext/polars/src/{apply → map}/dataframe.rs +28 -33
  35. data/ext/polars/src/{apply → map}/mod.rs +10 -6
  36. data/ext/polars/src/{apply → map}/series.rs +12 -16
  37. data/ext/polars/src/object.rs +2 -2
  38. data/ext/polars/src/rb_modules.rs +25 -6
  39. data/ext/polars/src/series/construction.rs +32 -6
  40. data/ext/polars/src/series/export.rs +2 -2
  41. data/ext/polars/src/series/set_at_idx.rs +33 -17
  42. data/ext/polars/src/series.rs +62 -42
  43. data/ext/polars/src/sql.rs +46 -0
  44. data/lib/polars/array_expr.rb +84 -0
  45. data/lib/polars/array_name_space.rb +77 -0
  46. data/lib/polars/batched_csv_reader.rb +1 -1
  47. data/lib/polars/config.rb +530 -0
  48. data/lib/polars/data_frame.rb +206 -131
  49. data/lib/polars/data_types.rb +163 -29
  50. data/lib/polars/date_time_expr.rb +13 -18
  51. data/lib/polars/date_time_name_space.rb +22 -28
  52. data/lib/polars/dynamic_group_by.rb +2 -2
  53. data/lib/polars/expr.rb +241 -151
  54. data/lib/polars/functions.rb +29 -38
  55. data/lib/polars/group_by.rb +38 -76
  56. data/lib/polars/io.rb +37 -2
  57. data/lib/polars/lazy_frame.rb +174 -95
  58. data/lib/polars/lazy_functions.rb +87 -63
  59. data/lib/polars/lazy_group_by.rb +7 -8
  60. data/lib/polars/list_expr.rb +40 -36
  61. data/lib/polars/list_name_space.rb +15 -15
  62. data/lib/polars/name_expr.rb +198 -0
  63. data/lib/polars/rolling_group_by.rb +6 -4
  64. data/lib/polars/series.rb +95 -28
  65. data/lib/polars/sql_context.rb +194 -0
  66. data/lib/polars/string_expr.rb +249 -69
  67. data/lib/polars/string_name_space.rb +155 -25
  68. data/lib/polars/utils.rb +119 -57
  69. data/lib/polars/version.rb +1 -1
  70. data/lib/polars.rb +6 -0
  71. metadata +21 -7
  72. /data/ext/polars/src/{apply → map}/lazy.rs +0 -0
@@ -1,4 +1,4 @@
1
- use magnus::{class, IntoValue, RArray, TryConvert, Value};
1
+ use magnus::{class, prelude::*, typed_data::Obj, IntoValue, RArray, TryConvert, Value};
2
2
  use polars::prelude::*;
3
3
  use polars_core::frame::row::{rows_to_schema_first_non_null, Row};
4
4
  use polars_core::series::SeriesIter;
@@ -34,20 +34,20 @@ pub fn apply_lambda_unknown<'a>(
34
34
  null_count += 1;
35
35
  continue;
36
36
  } else if out.is_kind_of(class::true_class()) || out.is_kind_of(class::false_class()) {
37
- let first_value = out.try_convert::<bool>().ok();
37
+ let first_value = bool::try_convert(out).ok();
38
38
  return Ok((
39
- RbSeries::new(
39
+ Obj::wrap(RbSeries::new(
40
40
  apply_lambda_with_bool_out_type(df, lambda, null_count, first_value)
41
41
  .into_series(),
42
- )
43
- .into(),
42
+ ))
43
+ .as_value(),
44
44
  false,
45
45
  ));
46
46
  } else if out.is_kind_of(class::float()) {
47
- let first_value = out.try_convert::<f64>().ok();
47
+ let first_value = f64::try_convert(out).ok();
48
48
 
49
49
  return Ok((
50
- RbSeries::new(
50
+ Obj::wrap(RbSeries::new(
51
51
  apply_lambda_with_primitive_out_type::<Float64Type>(
52
52
  df,
53
53
  lambda,
@@ -55,14 +55,14 @@ pub fn apply_lambda_unknown<'a>(
55
55
  first_value,
56
56
  )
57
57
  .into_series(),
58
- )
59
- .into(),
58
+ ))
59
+ .as_value(),
60
60
  false,
61
61
  ));
62
62
  } else if out.is_kind_of(class::integer()) {
63
- let first_value = out.try_convert::<i64>().ok();
63
+ let first_value = i64::try_convert(out).ok();
64
64
  return Ok((
65
- RbSeries::new(
65
+ Obj::wrap(RbSeries::new(
66
66
  apply_lambda_with_primitive_out_type::<Int64Type>(
67
67
  df,
68
68
  lambda,
@@ -70,12 +70,12 @@ pub fn apply_lambda_unknown<'a>(
70
70
  first_value,
71
71
  )
72
72
  .into_series(),
73
- )
74
- .into(),
73
+ ))
74
+ .as_value(),
75
75
  false,
76
76
  ));
77
77
  // } else if out.is_kind_of(class::string()) {
78
- // let first_value = out.try_convert::<String>().ok();
78
+ // let first_value = String::try_convert(out).ok();
79
79
  // return Ok((
80
80
  // RbSeries::new(
81
81
  // apply_lambda_with_utf8_out_type(df, lambda, null_count, first_value)
@@ -85,25 +85,21 @@ pub fn apply_lambda_unknown<'a>(
85
85
  // false,
86
86
  // ));
87
87
  } else if out.respond_to("_s", true)? {
88
- let rb_rbseries: Value = out.funcall("_s", ()).unwrap();
89
- let series = rb_rbseries
90
- .try_convert::<&RbSeries>()
91
- .unwrap()
92
- .series
93
- .borrow();
88
+ let rb_rbseries: Obj<RbSeries> = out.funcall("_s", ()).unwrap();
89
+ let series = rb_rbseries.series.borrow();
94
90
  let dt = series.dtype();
95
91
  return Ok((
96
- RbSeries::new(
92
+ Obj::wrap(RbSeries::new(
97
93
  apply_lambda_with_list_out_type(df, lambda, null_count, Some(&series), dt)?
98
94
  .into_series(),
99
- )
100
- .into(),
95
+ ))
96
+ .as_value(),
101
97
  false,
102
98
  ));
103
- } else if out.try_convert::<Wrap<Row<'a>>>().is_ok() {
104
- let first_value = out.try_convert::<Wrap<Row<'a>>>().unwrap().0;
99
+ } else if Wrap::<Row<'a>>::try_convert(out).is_ok() {
100
+ let first_value = Wrap::<Row<'a>>::try_convert(out).unwrap().0;
105
101
  return Ok((
106
- RbDataFrame::from(
102
+ Obj::wrap(RbDataFrame::from(
107
103
  apply_lambda_with_rows_output(
108
104
  df,
109
105
  lambda,
@@ -112,8 +108,8 @@ pub fn apply_lambda_unknown<'a>(
112
108
  inference_size,
113
109
  )
114
110
  .map_err(RbPolarsErr::from)?,
115
- )
116
- .into(),
111
+ ))
112
+ .as_value(),
117
113
  true,
118
114
  ));
119
115
  } else if out.is_kind_of(class::array()) {
@@ -143,7 +139,7 @@ where
143
139
  let iter = iters.iter_mut().map(|it| Wrap(it.next().unwrap()));
144
140
  let tpl = (RArray::from_iter(iter),);
145
141
  match lambda.funcall::<_, _, Value>("call", tpl) {
146
- Ok(val) => val.try_convert::<T>().ok(),
142
+ Ok(val) => T::try_convert(val).ok(),
147
143
  Err(e) => panic!("ruby function failed {}", e),
148
144
  }
149
145
  })
@@ -219,8 +215,7 @@ pub fn apply_lambda_with_list_out_type(
219
215
  let tpl = (RArray::from_iter(iter),);
220
216
  match lambda.funcall::<_, _, Value>("call", tpl) {
221
217
  Ok(val) => match val.funcall::<_, _, Value>("_s", ()) {
222
- Ok(val) => val
223
- .try_convert::<&RbSeries>()
218
+ Ok(val) => Obj::<RbSeries>::try_convert(val)
224
219
  .ok()
225
220
  .map(|ps| ps.series.borrow().clone()),
226
221
  Err(_) => {
@@ -257,11 +252,11 @@ pub fn apply_lambda_with_rows_output<'a>(
257
252
  let tpl = (RArray::from_iter(iter),);
258
253
  match lambda.funcall::<_, _, Value>("call", tpl) {
259
254
  Ok(val) => {
260
- match val.try_convert::<RArray>().ok() {
255
+ match RArray::try_convert(val).ok() {
261
256
  Some(tuple) => {
262
257
  row_buf.0.clear();
263
258
  for v in tuple.each() {
264
- let v = v.unwrap().try_convert::<Wrap<AnyValue>>().unwrap().0;
259
+ let v = Wrap::<AnyValue>::try_convert(v.unwrap()).unwrap().0;
265
260
  row_buf.0.push(v);
266
261
  }
267
262
  let ptr = &row_buf as *const Row;
@@ -2,7 +2,7 @@ pub mod dataframe;
2
2
  pub mod lazy;
3
3
  pub mod series;
4
4
 
5
- use magnus::{RHash, Value};
5
+ use magnus::{prelude::*, RHash, Value};
6
6
  use polars::chunked_array::builder::get_list_builder;
7
7
  use polars::prelude::*;
8
8
  use polars_core::export::rayon::prelude::*;
@@ -68,7 +68,7 @@ fn iterator_to_struct(
68
68
  }
69
69
  }
70
70
  Some(dict) => {
71
- let dict = dict.try_convert::<RHash>()?;
71
+ let dict = RHash::try_convert(dict)?;
72
72
  if dict.len() != struct_width {
73
73
  return Err(crate::error::ComputeError::new_err(
74
74
  format!("Cannot create struct type.\n> The struct dtype expects {} fields, but it got a dict with {} fields.", struct_width, dict.len())
@@ -78,7 +78,7 @@ fn iterator_to_struct(
78
78
  // the first item determines the output name
79
79
  todo!()
80
80
  // for ((_, val), field_items) in dict.iter().zip(&mut items) {
81
- // let item = val.try_convert::<Wrap<AnyValue>>()?;
81
+ // let item = Wrap::<AnyValue>::try_convert(val)?;
82
82
  // field_items.push(item.0)
83
83
  // }
84
84
  }
@@ -237,15 +237,19 @@ fn iterator_to_list(
237
237
  for _ in 0..init_null_count {
238
238
  builder.append_null()
239
239
  }
240
- builder.append_opt_series(first_value);
240
+ builder
241
+ .append_opt_series(first_value)
242
+ .map_err(RbPolarsErr::from)?;
241
243
  for opt_val in it {
242
244
  match opt_val {
243
245
  None => builder.append_null(),
244
246
  Some(s) => {
245
247
  if s.len() == 0 && s.dtype() != dt {
246
- builder.append_series(&Series::full_null("", 0, dt))
248
+ builder
249
+ .append_series(&Series::full_null("", 0, dt))
250
+ .unwrap()
247
251
  } else {
248
- builder.append_series(&s)
252
+ builder.append_series(&s).map_err(RbPolarsErr::from)?
249
253
  }
250
254
  }
251
255
  }
@@ -1,4 +1,4 @@
1
- use magnus::{class, IntoValue, RHash, TryConvert, Value};
1
+ use magnus::{class, prelude::*, typed_data::Obj, IntoValue, RHash, TryConvert, Value};
2
2
  use polars::prelude::*;
3
3
 
4
4
  use super::*;
@@ -14,12 +14,12 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>(
14
14
  null_count: usize,
15
15
  ) -> RbResult<RbSeries> {
16
16
  if out.is_kind_of(class::true_class()) || out.is_kind_of(class::false_class()) {
17
- let first_value = out.try_convert::<bool>().unwrap();
17
+ let first_value = bool::try_convert(out).unwrap();
18
18
  applyer
19
19
  .apply_lambda_with_bool_out_type(lambda, null_count, Some(first_value))
20
20
  .map(|ca| ca.into_series().into())
21
21
  } else if out.is_kind_of(class::float()) {
22
- let first_value = out.try_convert::<f64>().unwrap();
22
+ let first_value = f64::try_convert(out).unwrap();
23
23
  applyer
24
24
  .apply_lambda_with_primitive_out_type::<Float64Type>(
25
25
  lambda,
@@ -28,7 +28,7 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>(
28
28
  )
29
29
  .map(|ca| ca.into_series().into())
30
30
  } else if out.is_kind_of(class::string()) {
31
- let first_value = out.try_convert::<String>().unwrap();
31
+ let first_value = String::try_convert(out).unwrap();
32
32
  applyer
33
33
  .apply_lambda_with_utf8_out_type(lambda, null_count, Some(first_value.as_str()))
34
34
  .map(|ca| ca.into_series().into())
@@ -37,13 +37,13 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>(
37
37
  } else if out.is_kind_of(class::array()) {
38
38
  todo!()
39
39
  } else if out.is_kind_of(class::hash()) {
40
- let first = out.try_convert::<Wrap<AnyValue<'_>>>()?;
40
+ let first = Wrap::<AnyValue<'_>>::try_convert(out)?;
41
41
  applyer.apply_to_struct(lambda, null_count, first.0)
42
42
  }
43
43
  // this succeeds for numpy ints as well, where checking if it is pyint fails
44
44
  // we do this later in the chain so that we don't extract integers from string chars.
45
- else if out.try_convert::<i64>().is_ok() {
46
- let first_value = out.try_convert::<i64>().unwrap();
45
+ else if i64::try_convert(out).is_ok() {
46
+ let first_value = i64::try_convert(out).unwrap();
47
47
  applyer
48
48
  .apply_lambda_with_primitive_out_type::<Int64Type>(
49
49
  lambda,
@@ -51,7 +51,7 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>(
51
51
  Some(first_value),
52
52
  )
53
53
  .map(|ca| ca.into_series().into())
54
- } else if let Ok(av) = out.try_convert::<Wrap<AnyValue>>() {
54
+ } else if let Ok(av) = Wrap::<AnyValue>::try_convert(out) {
55
55
  applyer
56
56
  .apply_extract_any_values(lambda, null_count, av.0)
57
57
  .map(|s| s.into())
@@ -141,7 +141,7 @@ where
141
141
  S: TryConvert,
142
142
  {
143
143
  match call_lambda(lambda, in_val) {
144
- Ok(out) => out.try_convert::<S>(),
144
+ Ok(out) => S::try_convert(out),
145
145
  Err(e) => panic!("ruby function failed {}", e),
146
146
  }
147
147
  }
@@ -151,13 +151,9 @@ where
151
151
  T: IntoValue,
152
152
  {
153
153
  let out: Value = lambda.funcall("call", (in_val,))?;
154
- let py_series: Value = out.funcall("_s", ())?;
155
- Ok(py_series
156
- .try_convert::<&RbSeries>()
157
- .unwrap()
158
- .series
159
- .borrow()
160
- .clone())
154
+ let py_series: Obj<RbSeries> = out.funcall("_s", ())?;
155
+ let tmp = py_series.series.borrow();
156
+ Ok(tmp.clone())
161
157
  }
162
158
 
163
159
  impl<'a> ApplyLambda<'a> for BooleanChunked {
@@ -10,7 +10,7 @@ use polars_core::prelude::AnyValue;
10
10
  use crate::prelude::ObjectValue;
11
11
  use crate::Wrap;
12
12
 
13
- // pub(crate) const OBJECT_NAME: &str = "object";
13
+ pub(crate) const OBJECT_NAME: &str = "object";
14
14
 
15
15
  pub(crate) fn register_object_builder() {
16
16
  if !registry::is_object_builder_registered() {
@@ -21,7 +21,7 @@ pub(crate) fn register_object_builder() {
21
21
 
22
22
  let object_converter = Arc::new(|av: AnyValue| {
23
23
  let object = ObjectValue {
24
- inner: Wrap(av).into_value(),
24
+ inner: Wrap(av).into_value().into(),
25
25
  };
26
26
  Box::new(object) as Box<dyn Any>
27
27
  });
@@ -1,21 +1,40 @@
1
- use magnus::{class, memoize, Module, RClass, RModule};
1
+ use magnus::{value::Lazy, Module, RClass, RModule, Ruby};
2
+
3
+ static POLARS: Lazy<RModule> = Lazy::new(|ruby| ruby.class_object().const_get("Polars").unwrap());
2
4
 
3
5
  pub(crate) fn polars() -> RModule {
4
- *memoize!(RModule: class::object().const_get("Polars").unwrap())
6
+ Ruby::get().unwrap().get_inner(&POLARS)
5
7
  }
6
8
 
9
+ static SERIES: Lazy<RClass> =
10
+ Lazy::new(|ruby| ruby.get_inner(&POLARS).const_get("Series").unwrap());
11
+
7
12
  pub(crate) fn series() -> RClass {
8
- *memoize!(RClass: polars().const_get("Series").unwrap())
13
+ Ruby::get().unwrap().get_inner(&SERIES)
9
14
  }
10
15
 
16
+ static UTILS: Lazy<RModule> = Lazy::new(|ruby| ruby.get_inner(&POLARS).const_get("Utils").unwrap());
17
+
11
18
  pub(crate) fn utils() -> RModule {
12
- *memoize!(RModule: polars().const_get("Utils").unwrap())
19
+ Ruby::get().unwrap().get_inner(&UTILS)
20
+ }
21
+
22
+ static BIGDECIMAL: Lazy<RClass> =
23
+ Lazy::new(|ruby| ruby.class_object().const_get("BigDecimal").unwrap());
24
+
25
+ pub(crate) fn bigdecimal() -> RClass {
26
+ Ruby::get().unwrap().get_inner(&BIGDECIMAL)
13
27
  }
14
28
 
29
+ static DATE: Lazy<RClass> = Lazy::new(|ruby| ruby.class_object().const_get("Date").unwrap());
30
+
15
31
  pub(crate) fn date() -> RClass {
16
- *memoize!(RClass: class::object().const_get("Date").unwrap())
32
+ Ruby::get().unwrap().get_inner(&DATE)
17
33
  }
18
34
 
35
+ static DATETIME: Lazy<RClass> =
36
+ Lazy::new(|ruby| ruby.class_object().const_get("DateTime").unwrap());
37
+
19
38
  pub(crate) fn datetime() -> RClass {
20
- *memoize!(RClass: class::object().const_get("DateTime").unwrap())
39
+ Ruby::get().unwrap().get_inner(&DATETIME)
21
40
  }
@@ -1,10 +1,10 @@
1
- use magnus::RArray;
1
+ use magnus::{prelude::*, RArray};
2
2
  use polars_core::prelude::*;
3
3
 
4
- use crate::conversion::{slice_extract_wrapped, Wrap};
4
+ use crate::conversion::{slice_extract_wrapped, vec_extract_wrapped, Wrap};
5
5
  use crate::prelude::ObjectValue;
6
6
  use crate::series::to_series_collection;
7
- use crate::{RbPolarsErr, RbResult, RbSeries};
7
+ use crate::{RbPolarsErr, RbResult, RbSeries, RbValueError};
8
8
 
9
9
  impl RbSeries {
10
10
  pub fn new_opt_bool(name: String, obj: RArray, strict: bool) -> RbResult<RbSeries> {
@@ -16,7 +16,7 @@ impl RbSeries {
16
16
  if item.is_nil() {
17
17
  builder.append_null()
18
18
  } else {
19
- match item.try_convert::<bool>() {
19
+ match bool::try_convert(*item) {
20
20
  Ok(val) => builder.append_value(val),
21
21
  Err(e) => {
22
22
  if strict {
@@ -49,7 +49,7 @@ where
49
49
  if item.is_nil() {
50
50
  builder.append_null()
51
51
  } else {
52
- match item.try_convert::<T::Native>() {
52
+ match T::Native::try_convert(*item) {
53
53
  Ok(val) => builder.append_value(val),
54
54
  Err(e) => {
55
55
  if strict {
@@ -92,7 +92,7 @@ init_method_opt!(new_opt_f64, Float64Type, f64);
92
92
  fn vec_wrap_any_value<'s>(arr: RArray) -> RbResult<Vec<Wrap<AnyValue<'s>>>> {
93
93
  let mut val = Vec::with_capacity(arr.len());
94
94
  for v in arr.each() {
95
- val.push(v?.try_convert()?);
95
+ val.push(Wrap::<AnyValue<'s>>::try_convert(v?)?);
96
96
  }
97
97
  Ok(val)
98
98
  }
@@ -137,6 +137,32 @@ impl RbSeries {
137
137
  Ok(Series::new(&name, &series_vec).into())
138
138
  }
139
139
 
140
+ pub fn new_array(
141
+ width: usize,
142
+ inner: Option<Wrap<DataType>>,
143
+ name: String,
144
+ val: RArray,
145
+ _strict: bool,
146
+ ) -> RbResult<Self> {
147
+ let val = vec_wrap_any_value(val)?;
148
+ let val = vec_extract_wrapped(val);
149
+ let out = Series::new(&name, &val);
150
+ match out.dtype() {
151
+ DataType::List(list_inner) => {
152
+ let out = out
153
+ .cast(&DataType::Array(
154
+ Box::new(inner.map(|dt| dt.0).unwrap_or(*list_inner.clone())),
155
+ width,
156
+ ))
157
+ .map_err(RbPolarsErr::from)?;
158
+ Ok(out.into())
159
+ }
160
+ _ => Err(RbValueError::new_err(
161
+ "could not create Array from input".to_string(),
162
+ )),
163
+ }
164
+ }
165
+
140
166
  pub fn new_decimal(name: String, val: RArray, strict: bool) -> RbResult<Self> {
141
167
  let val = vec_wrap_any_value(val)?;
142
168
  // TODO: do we have to respect 'strict' here? it's possible if we want to
@@ -1,4 +1,4 @@
1
- use magnus::{class, Module, RArray, RClass, RModule, Value};
1
+ use magnus::{class, prelude::*, Module, RArray, RClass, RModule, Value};
2
2
  use polars_core::prelude::*;
3
3
 
4
4
  use crate::{raise_err, RbPolarsErr, RbResult, RbSeries};
@@ -13,7 +13,7 @@ impl RbSeries {
13
13
  let ca = s.utf8().unwrap();
14
14
 
15
15
  // TODO make more efficient
16
- let np_arr = RArray::from_iter(ca.into_iter());
16
+ let np_arr = RArray::from_iter(ca);
17
17
  class::object()
18
18
  .const_get::<_, RModule>("Numo")?
19
19
  .const_get::<_, RClass>("RObject")?
@@ -1,18 +1,34 @@
1
- // use polars::export::arrow2::array::Array;
1
+ use polars::export::arrow::array::Array;
2
2
  use polars::prelude::*;
3
3
 
4
- pub fn set_at_idx(mut s: Series, idx: &Series, values: &Series) -> PolarsResult<Series> {
4
+ use crate::error::RbPolarsErr;
5
+ use crate::{RbResult, RbSeries};
6
+
7
+ impl RbSeries {
8
+ pub fn set_at_idx(&self, idx: &RbSeries, values: &RbSeries) -> RbResult<()> {
9
+ let mut s = self.series.borrow_mut();
10
+ match set_at_idx(s.clone(), &idx.series.borrow(), &values.series.borrow()) {
11
+ Ok(out) => {
12
+ *s = out;
13
+ Ok(())
14
+ }
15
+ Err(e) => Err(RbPolarsErr::from(e)),
16
+ }
17
+ }
18
+ }
19
+
20
+ fn set_at_idx(mut s: Series, idx: &Series, values: &Series) -> PolarsResult<Series> {
5
21
  let logical_dtype = s.dtype().clone();
6
22
  let idx = idx.cast(&IDX_DTYPE)?;
7
23
  let idx = idx.rechunk();
8
24
  let idx = idx.idx().unwrap();
9
25
  let idx = idx.downcast_iter().next().unwrap();
10
26
 
11
- // if idx.null_count() > 0 {
12
- // return Err(PolarsError::ComputeError(
13
- // "index values should not be null".into(),
14
- // ));
15
- // }
27
+ if idx.null_count() > 0 {
28
+ return Err(PolarsError::ComputeError(
29
+ "index values should not be null".into(),
30
+ ));
31
+ }
16
32
 
17
33
  let idx = idx.values().as_slice();
18
34
 
@@ -27,52 +43,52 @@ pub fn set_at_idx(mut s: Series, idx: &Series, values: &Series) -> PolarsResult<
27
43
  DataType::Int8 => {
28
44
  let ca: &mut ChunkedArray<Int8Type> = mutable_s.as_mut();
29
45
  let values = values.i8()?;
30
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
46
+ std::mem::take(ca).set_at_idx2(idx, values)
31
47
  }
32
48
  DataType::Int16 => {
33
49
  let ca: &mut ChunkedArray<Int16Type> = mutable_s.as_mut();
34
50
  let values = values.i16()?;
35
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
51
+ std::mem::take(ca).set_at_idx2(idx, values)
36
52
  }
37
53
  DataType::Int32 => {
38
54
  let ca: &mut ChunkedArray<Int32Type> = mutable_s.as_mut();
39
55
  let values = values.i32()?;
40
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
56
+ std::mem::take(ca).set_at_idx2(idx, values)
41
57
  }
42
58
  DataType::Int64 => {
43
59
  let ca: &mut ChunkedArray<Int64Type> = mutable_s.as_mut();
44
60
  let values = values.i64()?;
45
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
61
+ std::mem::take(ca).set_at_idx2(idx, values)
46
62
  }
47
63
  DataType::UInt8 => {
48
64
  let ca: &mut ChunkedArray<UInt8Type> = mutable_s.as_mut();
49
65
  let values = values.u8()?;
50
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
66
+ std::mem::take(ca).set_at_idx2(idx, values)
51
67
  }
52
68
  DataType::UInt16 => {
53
69
  let ca: &mut ChunkedArray<UInt16Type> = mutable_s.as_mut();
54
70
  let values = values.u16()?;
55
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
71
+ std::mem::take(ca).set_at_idx2(idx, values)
56
72
  }
57
73
  DataType::UInt32 => {
58
74
  let ca: &mut ChunkedArray<UInt32Type> = mutable_s.as_mut();
59
75
  let values = values.u32()?;
60
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
76
+ std::mem::take(ca).set_at_idx2(idx, values)
61
77
  }
62
78
  DataType::UInt64 => {
63
79
  let ca: &mut ChunkedArray<UInt64Type> = mutable_s.as_mut();
64
80
  let values = values.u64()?;
65
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
81
+ std::mem::take(ca).set_at_idx2(idx, values)
66
82
  }
67
83
  DataType::Float32 => {
68
84
  let ca: &mut ChunkedArray<Float32Type> = mutable_s.as_mut();
69
85
  let values = values.f32()?;
70
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
86
+ std::mem::take(ca).set_at_idx2(idx, values)
71
87
  }
72
88
  DataType::Float64 => {
73
89
  let ca: &mut ChunkedArray<Float64Type> = mutable_s.as_mut();
74
90
  let values = values.f64()?;
75
- std::mem::take(ca).set_at_idx2(idx, values.into_iter())
91
+ std::mem::take(ca).set_at_idx2(idx, values)
76
92
  }
77
93
  DataType::Boolean => {
78
94
  let ca = s.bool()?;