polars-df 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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()?;