polars-df 0.10.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/Cargo.lock +392 -351
  4. data/README.md +6 -6
  5. data/ext/polars/Cargo.toml +12 -7
  6. data/ext/polars/src/batched_csv.rs +53 -52
  7. data/ext/polars/src/conversion/any_value.rs +261 -0
  8. data/ext/polars/src/conversion/chunked_array.rs +4 -4
  9. data/ext/polars/src/conversion/mod.rs +60 -66
  10. data/ext/polars/src/dataframe/construction.rs +184 -0
  11. data/ext/polars/src/dataframe/export.rs +48 -0
  12. data/ext/polars/src/dataframe/general.rs +597 -0
  13. data/ext/polars/src/dataframe/io.rs +473 -0
  14. data/ext/polars/src/dataframe/mod.rs +26 -0
  15. data/ext/polars/src/error.rs +26 -4
  16. data/ext/polars/src/expr/categorical.rs +0 -10
  17. data/ext/polars/src/expr/datetime.rs +4 -8
  18. data/ext/polars/src/expr/general.rs +129 -94
  19. data/ext/polars/src/expr/mod.rs +2 -2
  20. data/ext/polars/src/expr/rolling.rs +201 -77
  21. data/ext/polars/src/expr/string.rs +11 -36
  22. data/ext/polars/src/functions/eager.rs +10 -10
  23. data/ext/polars/src/functions/lazy.rs +23 -21
  24. data/ext/polars/src/functions/range.rs +69 -1
  25. data/ext/polars/src/interop/mod.rs +1 -0
  26. data/ext/polars/src/interop/numo/mod.rs +2 -0
  27. data/ext/polars/src/interop/numo/to_numo_df.rs +23 -0
  28. data/ext/polars/src/interop/numo/to_numo_series.rs +61 -0
  29. data/ext/polars/src/lazyframe/mod.rs +135 -136
  30. data/ext/polars/src/lib.rs +94 -59
  31. data/ext/polars/src/map/dataframe.rs +2 -2
  32. data/ext/polars/src/map/lazy.rs +5 -25
  33. data/ext/polars/src/map/series.rs +7 -1
  34. data/ext/polars/src/rb_modules.rs +25 -1
  35. data/ext/polars/src/series/aggregation.rs +49 -30
  36. data/ext/polars/src/series/arithmetic.rs +21 -11
  37. data/ext/polars/src/series/construction.rs +56 -38
  38. data/ext/polars/src/series/export.rs +131 -49
  39. data/ext/polars/src/series/mod.rs +32 -141
  40. data/ext/polars/src/sql.rs +3 -1
  41. data/lib/polars/array_expr.rb +4 -4
  42. data/lib/polars/batched_csv_reader.rb +11 -5
  43. data/lib/polars/cat_expr.rb +0 -36
  44. data/lib/polars/cat_name_space.rb +0 -37
  45. data/lib/polars/convert.rb +6 -1
  46. data/lib/polars/data_frame.rb +176 -403
  47. data/lib/polars/data_types.rb +1 -1
  48. data/lib/polars/date_time_expr.rb +525 -572
  49. data/lib/polars/date_time_name_space.rb +263 -460
  50. data/lib/polars/dynamic_group_by.rb +5 -5
  51. data/lib/polars/exceptions.rb +7 -0
  52. data/lib/polars/expr.rb +1394 -243
  53. data/lib/polars/expr_dispatch.rb +1 -1
  54. data/lib/polars/functions/aggregation/horizontal.rb +8 -8
  55. data/lib/polars/functions/as_datatype.rb +63 -40
  56. data/lib/polars/functions/lazy.rb +63 -14
  57. data/lib/polars/functions/lit.rb +1 -1
  58. data/lib/polars/functions/range/date_range.rb +90 -57
  59. data/lib/polars/functions/range/datetime_range.rb +149 -0
  60. data/lib/polars/functions/range/int_range.rb +2 -2
  61. data/lib/polars/functions/range/time_range.rb +141 -0
  62. data/lib/polars/functions/repeat.rb +1 -1
  63. data/lib/polars/functions/whenthen.rb +1 -1
  64. data/lib/polars/group_by.rb +88 -23
  65. data/lib/polars/io/avro.rb +24 -0
  66. data/lib/polars/{io.rb → io/csv.rb} +299 -493
  67. data/lib/polars/io/database.rb +73 -0
  68. data/lib/polars/io/ipc.rb +247 -0
  69. data/lib/polars/io/json.rb +29 -0
  70. data/lib/polars/io/ndjson.rb +80 -0
  71. data/lib/polars/io/parquet.rb +227 -0
  72. data/lib/polars/lazy_frame.rb +143 -272
  73. data/lib/polars/lazy_group_by.rb +100 -3
  74. data/lib/polars/list_expr.rb +11 -11
  75. data/lib/polars/list_name_space.rb +5 -1
  76. data/lib/polars/rolling_group_by.rb +7 -9
  77. data/lib/polars/series.rb +103 -187
  78. data/lib/polars/string_expr.rb +78 -102
  79. data/lib/polars/string_name_space.rb +5 -4
  80. data/lib/polars/testing.rb +2 -2
  81. data/lib/polars/utils/constants.rb +9 -0
  82. data/lib/polars/utils/convert.rb +97 -0
  83. data/lib/polars/utils/parse.rb +89 -0
  84. data/lib/polars/utils/various.rb +76 -0
  85. data/lib/polars/utils/wrap.rb +19 -0
  86. data/lib/polars/utils.rb +8 -300
  87. data/lib/polars/version.rb +1 -1
  88. data/lib/polars/whenthen.rb +6 -6
  89. data/lib/polars.rb +20 -1
  90. metadata +28 -7
  91. data/ext/polars/src/conversion/anyvalue.rs +0 -186
  92. data/ext/polars/src/dataframe.rs +0 -1208
@@ -5,6 +5,7 @@ mod error;
5
5
  mod expr;
6
6
  mod file;
7
7
  mod functions;
8
+ mod interop;
8
9
  mod lazyframe;
9
10
  mod lazygroupby;
10
11
  mod map;
@@ -59,18 +60,26 @@ fn init(ruby: &Ruby) -> RbResult<()> {
59
60
  class.define_singleton_method("read_csv", function!(RbDataFrame::read_csv, -1))?;
60
61
  class.define_singleton_method("read_parquet", function!(RbDataFrame::read_parquet, 9))?;
61
62
  class.define_singleton_method("read_ipc", function!(RbDataFrame::read_ipc, 6))?;
63
+ class.define_singleton_method(
64
+ "read_ipc_stream",
65
+ function!(RbDataFrame::read_ipc_stream, 6),
66
+ )?;
62
67
  class.define_singleton_method("read_avro", function!(RbDataFrame::read_avro, 4))?;
63
- class.define_singleton_method("read_rows", function!(RbDataFrame::read_rows, 3))?;
64
- class.define_singleton_method("read_hashes", function!(RbDataFrame::read_hashes, 4))?;
65
- class.define_singleton_method("read_hash", function!(RbDataFrame::read_hash, 1))?;
66
- class.define_singleton_method("read_json", function!(RbDataFrame::read_json, 1))?;
67
- class.define_singleton_method("read_ndjson", function!(RbDataFrame::read_ndjson, 1))?;
68
+ class.define_singleton_method("from_rows", function!(RbDataFrame::from_rows, 3))?;
69
+ class.define_singleton_method("from_hashes", function!(RbDataFrame::from_hashes, 5))?;
70
+ class.define_singleton_method("read_json", function!(RbDataFrame::read_json, 4))?;
71
+ class.define_singleton_method("read_ndjson", function!(RbDataFrame::read_ndjson, 4))?;
68
72
  class.define_method("estimated_size", method!(RbDataFrame::estimated_size, 0))?;
73
+ class.define_method("dtype_strings", method!(RbDataFrame::dtype_strings, 0))?;
69
74
  class.define_method("write_avro", method!(RbDataFrame::write_avro, 2))?;
70
75
  class.define_method("write_json", method!(RbDataFrame::write_json, 3))?;
71
76
  class.define_method("write_ndjson", method!(RbDataFrame::write_ndjson, 1))?;
72
77
  class.define_method("write_csv", method!(RbDataFrame::write_csv, 10))?;
73
78
  class.define_method("write_ipc", method!(RbDataFrame::write_ipc, 2))?;
79
+ class.define_method(
80
+ "write_ipc_stream",
81
+ method!(RbDataFrame::write_ipc_stream, 2),
82
+ )?;
74
83
  class.define_method("row_tuple", method!(RbDataFrame::row_tuple, 1))?;
75
84
  class.define_method("row_tuples", method!(RbDataFrame::row_tuples, 0))?;
76
85
  class.define_method("to_numo", method!(RbDataFrame::to_numo, 0))?;
@@ -88,7 +97,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
88
97
  class.define_method("sample_n", method!(RbDataFrame::sample_n, 4))?;
89
98
  class.define_method("sample_frac", method!(RbDataFrame::sample_frac, 4))?;
90
99
  class.define_method("rechunk", method!(RbDataFrame::rechunk, 0))?;
91
- class.define_method("to_s", method!(RbDataFrame::to_s, 0))?;
100
+ class.define_method("to_s", method!(RbDataFrame::as_str, 0))?;
92
101
  class.define_method("get_columns", method!(RbDataFrame::get_columns, 0))?;
93
102
  class.define_method("columns", method!(RbDataFrame::columns, 0))?;
94
103
  class.define_method(
@@ -106,8 +115,6 @@ fn init(ruby: &Ruby) -> RbResult<()> {
106
115
  class.define_method("vstack_mut", method!(RbDataFrame::vstack_mut, 1))?;
107
116
  class.define_method("vstack", method!(RbDataFrame::vstack, 1))?;
108
117
  class.define_method("drop_in_place", method!(RbDataFrame::drop_in_place, 1))?;
109
- class.define_method("drop_nulls", method!(RbDataFrame::drop_nulls, 1))?;
110
- class.define_method("drop", method!(RbDataFrame::drop, 1))?;
111
118
  class.define_method("select_at_idx", method!(RbDataFrame::select_at_idx, 1))?;
112
119
  class.define_method(
113
120
  "get_column_index",
@@ -115,7 +122,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
115
122
  )?;
116
123
  class.define_method("get_column", method!(RbDataFrame::get_column, 1))?;
117
124
  class.define_method("select", method!(RbDataFrame::select, 1))?;
118
- class.define_method("take", method!(RbDataFrame::take, 1))?;
125
+ class.define_method("take", method!(RbDataFrame::gather, 1))?;
119
126
  class.define_method(
120
127
  "take_with_series",
121
128
  method!(RbDataFrame::take_with_series, 1),
@@ -131,10 +138,9 @@ fn init(ruby: &Ruby) -> RbResult<()> {
131
138
  class.define_method("equals", method!(RbDataFrame::equals, 2))?;
132
139
  class.define_method("with_row_index", method!(RbDataFrame::with_row_index, 2))?;
133
140
  class.define_method("_clone", method!(RbDataFrame::clone, 0))?;
134
- class.define_method("melt", method!(RbDataFrame::melt, 4))?;
141
+ class.define_method("unpivot", method!(RbDataFrame::unpivot, 4))?;
135
142
  class.define_method("pivot_expr", method!(RbDataFrame::pivot_expr, 7))?;
136
143
  class.define_method("partition_by", method!(RbDataFrame::partition_by, 3))?;
137
- class.define_method("shift", method!(RbDataFrame::shift, 1))?;
138
144
  class.define_method("lazy", method!(RbDataFrame::lazy, 0))?;
139
145
  class.define_method("mean_horizontal", method!(RbDataFrame::mean_horizontal, 1))?;
140
146
  class.define_method("max_horizontal", method!(RbDataFrame::max_horizontal, 0))?;
@@ -142,11 +148,11 @@ fn init(ruby: &Ruby) -> RbResult<()> {
142
148
  class.define_method("sum_horizontal", method!(RbDataFrame::sum_horizontal, 1))?;
143
149
  class.define_method("to_dummies", method!(RbDataFrame::to_dummies, 3))?;
144
150
  class.define_method("null_count", method!(RbDataFrame::null_count, 0))?;
145
- class.define_method("apply", method!(RbDataFrame::apply, 3))?;
151
+ class.define_method("map_rows", method!(RbDataFrame::map_rows, 3))?;
146
152
  class.define_method("shrink_to_fit", method!(RbDataFrame::shrink_to_fit, 0))?;
147
153
  class.define_method("hash_rows", method!(RbDataFrame::hash_rows, 4))?;
148
154
  class.define_method("transpose", method!(RbDataFrame::transpose, 2))?;
149
- class.define_method("upsample", method!(RbDataFrame::upsample, 5))?;
155
+ class.define_method("upsample", method!(RbDataFrame::upsample, 4))?;
150
156
  class.define_method("to_struct", method!(RbDataFrame::to_struct, 1))?;
151
157
  class.define_method("unnest", method!(RbDataFrame::unnest, 1))?;
152
158
  class.define_method("clear", method!(RbDataFrame::clear, 0))?;
@@ -199,20 +205,23 @@ fn init(ruby: &Ruby) -> RbResult<()> {
199
205
  class.define_method("agg_groups", method!(RbExpr::agg_groups, 0))?;
200
206
  class.define_method("count", method!(RbExpr::count, 0))?;
201
207
  class.define_method("len", method!(RbExpr::len, 0))?;
202
- class.define_method("value_counts", method!(RbExpr::value_counts, 2))?;
208
+ class.define_method("value_counts", method!(RbExpr::value_counts, 4))?;
203
209
  class.define_method("unique_counts", method!(RbExpr::unique_counts, 0))?;
204
210
  class.define_method("null_count", method!(RbExpr::null_count, 0))?;
205
211
  class.define_method("cast", method!(RbExpr::cast, 2))?;
206
212
  class.define_method("sort_with", method!(RbExpr::sort_with, 2))?;
207
213
  class.define_method("arg_sort", method!(RbExpr::arg_sort, 2))?;
208
214
  class.define_method("top_k", method!(RbExpr::top_k, 1))?;
215
+ class.define_method("top_k_by", method!(RbExpr::top_k_by, 3))?;
209
216
  class.define_method("bottom_k", method!(RbExpr::bottom_k, 1))?;
217
+ class.define_method("bottom_k_by", method!(RbExpr::bottom_k_by, 3))?;
210
218
  class.define_method("peak_min", method!(RbExpr::peak_min, 0))?;
211
219
  class.define_method("peak_max", method!(RbExpr::peak_max, 0))?;
212
220
  class.define_method("arg_max", method!(RbExpr::arg_max, 0))?;
213
221
  class.define_method("arg_min", method!(RbExpr::arg_min, 0))?;
214
222
  class.define_method("search_sorted", method!(RbExpr::search_sorted, 2))?;
215
223
  class.define_method("gather", method!(RbExpr::gather, 1))?;
224
+ class.define_method("get", method!(RbExpr::get, 1))?;
216
225
  class.define_method("sort_by", method!(RbExpr::sort_by, 5))?;
217
226
  class.define_method("backward_fill", method!(RbExpr::backward_fill, 1))?;
218
227
  class.define_method("forward_fill", method!(RbExpr::forward_fill, 1))?;
@@ -230,6 +239,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
230
239
  class.define_method("std", method!(RbExpr::std, 1))?;
231
240
  class.define_method("var", method!(RbExpr::var, 1))?;
232
241
  class.define_method("is_unique", method!(RbExpr::is_unique, 0))?;
242
+ class.define_method("is_between", method!(RbExpr::is_between, 3))?;
233
243
  class.define_method("approx_n_unique", method!(RbExpr::approx_n_unique, 0))?;
234
244
  class.define_method("is_first_distinct", method!(RbExpr::is_first_distinct, 0))?;
235
245
  class.define_method("is_last_distinct", method!(RbExpr::is_last_distinct, 0))?;
@@ -287,7 +297,6 @@ fn init(ruby: &Ruby) -> RbResult<()> {
287
297
  class.define_method("str_strip_prefix", method!(RbExpr::str_strip_prefix, 1))?;
288
298
  class.define_method("str_strip_suffix", method!(RbExpr::str_strip_suffix, 1))?;
289
299
  class.define_method("str_slice", method!(RbExpr::str_slice, 2))?;
290
- class.define_method("str_explode", method!(RbExpr::str_explode, 0))?;
291
300
  class.define_method("str_to_uppercase", method!(RbExpr::str_to_uppercase, 0))?;
292
301
  class.define_method("str_to_lowercase", method!(RbExpr::str_to_lowercase, 0))?;
293
302
  class.define_method("str_len_bytes", method!(RbExpr::str_len_bytes, 0))?;
@@ -361,24 +370,24 @@ fn init(ruby: &Ruby) -> RbResult<()> {
361
370
  class.define_method("list_len", method!(RbExpr::list_len, 0))?;
362
371
  class.define_method("list_contains", method!(RbExpr::list_contains, 1))?;
363
372
  class.define_method("list_count_matches", method!(RbExpr::list_count_matches, 1))?;
364
- class.define_method("year", method!(RbExpr::dt_year, 0))?;
373
+ class.define_method("dt_year", method!(RbExpr::dt_year, 0))?;
365
374
  class.define_method("dt_is_leap_year", method!(RbExpr::dt_is_leap_year, 0))?;
366
- class.define_method("iso_year", method!(RbExpr::dt_iso_year, 0))?;
367
- class.define_method("quarter", method!(RbExpr::dt_quarter, 0))?;
368
- class.define_method("month", method!(RbExpr::dt_month, 0))?;
369
- class.define_method("week", method!(RbExpr::dt_week, 0))?;
370
- class.define_method("weekday", method!(RbExpr::dt_weekday, 0))?;
371
- class.define_method("day", method!(RbExpr::dt_day, 0))?;
372
- class.define_method("ordinal_day", method!(RbExpr::dt_ordinal_day, 0))?;
375
+ class.define_method("dt_iso_year", method!(RbExpr::dt_iso_year, 0))?;
376
+ class.define_method("dt_quarter", method!(RbExpr::dt_quarter, 0))?;
377
+ class.define_method("dt_month", method!(RbExpr::dt_month, 0))?;
378
+ class.define_method("dt_week", method!(RbExpr::dt_week, 0))?;
379
+ class.define_method("dt_weekday", method!(RbExpr::dt_weekday, 0))?;
380
+ class.define_method("dt_day", method!(RbExpr::dt_day, 0))?;
381
+ class.define_method("dt_ordinal_day", method!(RbExpr::dt_ordinal_day, 0))?;
373
382
  class.define_method("dt_time", method!(RbExpr::dt_time, 0))?;
374
383
  class.define_method("dt_date", method!(RbExpr::dt_date, 0))?;
375
384
  class.define_method("dt_datetime", method!(RbExpr::dt_datetime, 0))?;
376
- class.define_method("hour", method!(RbExpr::dt_hour, 0))?;
377
- class.define_method("minute", method!(RbExpr::dt_minute, 0))?;
378
- class.define_method("second", method!(RbExpr::dt_second, 0))?;
379
- class.define_method("millisecond", method!(RbExpr::dt_millisecond, 0))?;
380
- class.define_method("microsecond", method!(RbExpr::dt_microsecond, 0))?;
381
- class.define_method("nanosecond", method!(RbExpr::dt_nanosecond, 0))?;
385
+ class.define_method("dt_hour", method!(RbExpr::dt_hour, 0))?;
386
+ class.define_method("dt_minute", method!(RbExpr::dt_minute, 0))?;
387
+ class.define_method("dt_second", method!(RbExpr::dt_second, 0))?;
388
+ class.define_method("dt_millisecond", method!(RbExpr::dt_millisecond, 0))?;
389
+ class.define_method("dt_microsecond", method!(RbExpr::dt_microsecond, 0))?;
390
+ class.define_method("dt_nanosecond", method!(RbExpr::dt_nanosecond, 0))?;
382
391
  class.define_method("dt_total_days", method!(RbExpr::dt_total_days, 0))?;
383
392
  class.define_method("dt_total_hours", method!(RbExpr::dt_total_hours, 0))?;
384
393
  class.define_method("dt_total_minutes", method!(RbExpr::dt_total_minutes, 0))?;
@@ -395,7 +404,8 @@ fn init(ruby: &Ruby) -> RbResult<()> {
395
404
  "dt_total_milliseconds",
396
405
  method!(RbExpr::dt_total_milliseconds, 0),
397
406
  )?;
398
- class.define_method("timestamp", method!(RbExpr::dt_timestamp, 1))?;
407
+ class.define_method("dt_timestamp", method!(RbExpr::dt_timestamp, 1))?;
408
+ class.define_method("dt_to_string", method!(RbExpr::dt_to_string, 1))?;
399
409
  class.define_method("dt_offset_by", method!(RbExpr::dt_offset_by, 1))?;
400
410
  class.define_method("dt_epoch_seconds", method!(RbExpr::dt_epoch_seconds, 0))?;
401
411
  class.define_method("dt_with_time_unit", method!(RbExpr::dt_with_time_unit, 1))?;
@@ -408,27 +418,38 @@ fn init(ruby: &Ruby) -> RbResult<()> {
408
418
  "dt_replace_time_zone",
409
419
  method!(RbExpr::dt_replace_time_zone, 3),
410
420
  )?;
411
- class.define_method("dt_truncate", method!(RbExpr::dt_truncate, 2))?;
421
+ class.define_method("dt_truncate", method!(RbExpr::dt_truncate, 1))?;
412
422
  class.define_method("dt_month_start", method!(RbExpr::dt_month_start, 0))?;
413
423
  class.define_method("dt_month_end", method!(RbExpr::dt_month_end, 0))?;
414
424
  class.define_method("dt_base_utc_offset", method!(RbExpr::dt_base_utc_offset, 0))?;
415
425
  class.define_method("dt_dst_offset", method!(RbExpr::dt_dst_offset, 0))?;
416
- class.define_method("dt_round", method!(RbExpr::dt_round, 2))?;
426
+ class.define_method("dt_round", method!(RbExpr::dt_round, 1))?;
417
427
  class.define_method("dt_combine", method!(RbExpr::dt_combine, 2))?;
418
- class.define_method("map", method!(RbExpr::map, 3))?;
428
+ class.define_method("map_batches", method!(RbExpr::map_batches, 4))?;
419
429
  class.define_method("dot", method!(RbExpr::dot, 1))?;
420
430
  class.define_method("reinterpret", method!(RbExpr::reinterpret, 1))?;
421
431
  class.define_method("mode", method!(RbExpr::mode, 0))?;
422
432
  class.define_method("exclude", method!(RbExpr::exclude, 1))?;
423
433
  class.define_method("interpolate", method!(RbExpr::interpolate, 1))?;
424
- class.define_method("rolling_sum", method!(RbExpr::rolling_sum, 6))?;
425
- class.define_method("rolling_min", method!(RbExpr::rolling_min, 6))?;
426
- class.define_method("rolling_max", method!(RbExpr::rolling_max, 6))?;
427
- class.define_method("rolling_mean", method!(RbExpr::rolling_mean, 6))?;
428
- class.define_method("rolling_std", method!(RbExpr::rolling_std, 8))?;
429
- class.define_method("rolling_var", method!(RbExpr::rolling_var, 8))?;
430
- class.define_method("rolling_median", method!(RbExpr::rolling_median, 7))?;
431
- class.define_method("rolling_quantile", method!(RbExpr::rolling_quantile, 9))?;
434
+ class.define_method("rolling_sum", method!(RbExpr::rolling_sum, 4))?;
435
+ class.define_method("rolling_sum_by", method!(RbExpr::rolling_sum_by, 4))?;
436
+ class.define_method("rolling_min", method!(RbExpr::rolling_min, 4))?;
437
+ class.define_method("rolling_min_by", method!(RbExpr::rolling_min_by, 4))?;
438
+ class.define_method("rolling_max", method!(RbExpr::rolling_max, 4))?;
439
+ class.define_method("rolling_max_by", method!(RbExpr::rolling_max_by, 4))?;
440
+ class.define_method("rolling_mean", method!(RbExpr::rolling_mean, 4))?;
441
+ class.define_method("rolling_mean_by", method!(RbExpr::rolling_mean_by, 4))?;
442
+ class.define_method("rolling_std", method!(RbExpr::rolling_std, 5))?;
443
+ class.define_method("rolling_std_by", method!(RbExpr::rolling_std_by, 5))?;
444
+ class.define_method("rolling_var", method!(RbExpr::rolling_var, 5))?;
445
+ class.define_method("rolling_var_by", method!(RbExpr::rolling_var_by, 5))?;
446
+ class.define_method("rolling_median", method!(RbExpr::rolling_median, 4))?;
447
+ class.define_method("rolling_median_by", method!(RbExpr::rolling_median_by, 4))?;
448
+ class.define_method("rolling_quantile", method!(RbExpr::rolling_quantile, 6))?;
449
+ class.define_method(
450
+ "rolling_quantile_by",
451
+ method!(RbExpr::rolling_quantile_by, 6),
452
+ )?;
432
453
  class.define_method("rolling_skew", method!(RbExpr::rolling_skew, 2))?;
433
454
  class.define_method("lower_bound", method!(RbExpr::lower_bound, 0))?;
434
455
  class.define_method("upper_bound", method!(RbExpr::upper_bound, 0))?;
@@ -465,8 +486,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
465
486
  class.define_method("pct_change", method!(RbExpr::pct_change, 1))?;
466
487
  class.define_method("skew", method!(RbExpr::skew, 1))?;
467
488
  class.define_method("kurtosis", method!(RbExpr::kurtosis, 2))?;
468
- class.define_method("str_concat", method!(RbExpr::str_concat, 2))?;
469
- class.define_method("cat_set_ordering", method!(RbExpr::cat_set_ordering, 1))?;
489
+ class.define_method("str_join", method!(RbExpr::str_join, 2))?;
470
490
  class.define_method("cat_get_categories", method!(RbExpr::cat_get_categories, 0))?;
471
491
  class.define_method("reshape", method!(RbExpr::reshape, 1))?;
472
492
  class.define_method("cum_count", method!(RbExpr::cum_count, 1))?;
@@ -498,7 +518,8 @@ fn init(ruby: &Ruby) -> RbResult<()> {
498
518
  class.define_method("entropy", method!(RbExpr::entropy, 2))?;
499
519
  class.define_method("_hash", method!(RbExpr::hash, 4))?;
500
520
  class.define_method("set_sorted_flag", method!(RbExpr::set_sorted_flag, 1))?;
501
- class.define_method("replace", method!(RbExpr::replace, 4))?;
521
+ class.define_method("replace", method!(RbExpr::replace, 2))?;
522
+ class.define_method("replace_strict", method!(RbExpr::replace_strict, 4))?;
502
523
 
503
524
  // meta
504
525
  class.define_method("meta_pop", method!(RbExpr::meta_pop, 0))?;
@@ -531,7 +552,8 @@ fn init(ruby: &Ruby) -> RbResult<()> {
531
552
 
532
553
  // maybe add to different class
533
554
  let class = module.define_module("Plr")?;
534
- class.define_singleton_method("dtype_cols", function!(functions::lazy::dtype_cols2, 1))?;
555
+ class.define_singleton_method("dtype_cols", function!(functions::lazy::dtype_cols, 1))?;
556
+ class.define_singleton_method("index_cols", function!(functions::lazy::index_cols, 1))?;
535
557
  class.define_singleton_method("col", function!(functions::lazy::col, 1))?;
536
558
  class.define_singleton_method("len", function!(functions::lazy::len, 0))?;
537
559
  class.define_singleton_method("first", function!(functions::lazy::first, 0))?;
@@ -610,7 +632,18 @@ fn init(ruby: &Ruby) -> RbResult<()> {
610
632
  function!(functions::io::read_parquet_schema, 1),
611
633
  )?;
612
634
  class.define_singleton_method("collect_all", function!(functions::lazy::collect_all, 1))?;
613
- class.define_singleton_method("date_range", function!(functions::range::date_range, 6))?;
635
+ class.define_singleton_method("date_range", function!(functions::range::date_range, 4))?;
636
+ class.define_singleton_method("date_ranges", function!(functions::range::date_ranges, 4))?;
637
+ class.define_singleton_method(
638
+ "datetime_range",
639
+ function!(functions::range::datetime_range, 6),
640
+ )?;
641
+ class.define_singleton_method(
642
+ "datetime_ranges",
643
+ function!(functions::range::datetime_ranges, 6),
644
+ )?;
645
+ class.define_singleton_method("time_range", function!(functions::range::time_range, 4))?;
646
+ class.define_singleton_method("time_ranges", function!(functions::range::time_ranges, 4))?;
614
647
  class.define_singleton_method(
615
648
  "dtype_str_repr",
616
649
  function!(functions::misc::dtype_str_repr, 1),
@@ -689,7 +722,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
689
722
  class.define_singleton_method("new_from_csv", function!(RbLazyFrame::new_from_csv, -1))?;
690
723
  class.define_singleton_method(
691
724
  "new_from_parquet",
692
- function!(RbLazyFrame::new_from_parquet, 11),
725
+ function!(RbLazyFrame::new_from_parquet, 13),
693
726
  )?;
694
727
  class.define_singleton_method("new_from_ipc", function!(RbLazyFrame::new_from_ipc, 6))?;
695
728
  class.define_method("write_json", method!(RbLazyFrame::write_json, 1))?;
@@ -708,17 +741,17 @@ fn init(ruby: &Ruby) -> RbResult<()> {
708
741
  class.define_method("collect", method!(RbLazyFrame::collect, 0))?;
709
742
  class.define_method("sink_parquet", method!(RbLazyFrame::sink_parquet, 7))?;
710
743
  class.define_method("sink_ipc", method!(RbLazyFrame::sink_ipc, 3))?;
711
- class.define_method("sink_csv", method!(RbLazyFrame::sink_csv, 14))?;
744
+ class.define_method("sink_csv", method!(RbLazyFrame::sink_csv, 15))?;
712
745
  class.define_method("sink_json", method!(RbLazyFrame::sink_json, 2))?;
713
746
  class.define_method("fetch", method!(RbLazyFrame::fetch, 1))?;
714
747
  class.define_method("filter", method!(RbLazyFrame::filter, 1))?;
715
748
  class.define_method("select", method!(RbLazyFrame::select, 1))?;
716
749
  class.define_method("select_seq", method!(RbLazyFrame::select_seq, 1))?;
717
750
  class.define_method("group_by", method!(RbLazyFrame::group_by, 2))?;
718
- class.define_method("rolling", method!(RbLazyFrame::rolling, 6))?;
751
+ class.define_method("rolling", method!(RbLazyFrame::rolling, 5))?;
719
752
  class.define_method(
720
753
  "group_by_dynamic",
721
- method!(RbLazyFrame::group_by_dynamic, 10),
754
+ method!(RbLazyFrame::group_by_dynamic, 9),
722
755
  )?;
723
756
  class.define_method("with_context", method!(RbLazyFrame::with_context, 1))?;
724
757
  class.define_method("join_asof", method!(RbLazyFrame::join_asof, 11))?;
@@ -747,16 +780,13 @@ fn init(ruby: &Ruby) -> RbResult<()> {
747
780
  class.define_method("drop_nulls", method!(RbLazyFrame::drop_nulls, 1))?;
748
781
  class.define_method("slice", method!(RbLazyFrame::slice, 2))?;
749
782
  class.define_method("tail", method!(RbLazyFrame::tail, 1))?;
750
- class.define_method("melt", method!(RbLazyFrame::melt, 5))?;
783
+ class.define_method("unpivot", method!(RbLazyFrame::unpivot, 5))?;
751
784
  class.define_method("with_row_index", method!(RbLazyFrame::with_row_index, 2))?;
752
785
  class.define_method("drop", method!(RbLazyFrame::drop, 1))?;
753
786
  class.define_method("cast_all", method!(RbLazyFrame::cast_all, 2))?;
754
787
  class.define_method("_clone", method!(RbLazyFrame::clone, 0))?;
755
- class.define_method("columns", method!(RbLazyFrame::columns, 0))?;
756
- class.define_method("dtypes", method!(RbLazyFrame::dtypes, 0))?;
757
- class.define_method("schema", method!(RbLazyFrame::schema, 0))?;
788
+ class.define_method("collect_schema", method!(RbLazyFrame::collect_schema, 0))?;
758
789
  class.define_method("unnest", method!(RbLazyFrame::unnest, 1))?;
759
- class.define_method("width", method!(RbLazyFrame::width, 0))?;
760
790
  class.define_method("count", method!(RbLazyFrame::count, 0))?;
761
791
  class.define_method("merge_sorted", method!(RbLazyFrame::merge_sorted, 2))?;
762
792
 
@@ -778,8 +808,12 @@ fn init(ruby: &Ruby) -> RbResult<()> {
778
808
  class.define_singleton_method("new_opt_f32", function!(RbSeries::new_opt_f32, 3))?;
779
809
  class.define_singleton_method("new_opt_f64", function!(RbSeries::new_opt_f64, 3))?;
780
810
  class.define_singleton_method(
781
- "new_from_anyvalues",
782
- function!(RbSeries::new_from_anyvalues, 3),
811
+ "new_from_any_values",
812
+ function!(RbSeries::new_from_any_values, 3),
813
+ )?;
814
+ class.define_singleton_method(
815
+ "new_from_any_values_and_dtype",
816
+ function!(RbSeries::new_from_any_values_and_dtype, 4),
783
817
  )?;
784
818
  class.define_singleton_method("new_str", function!(RbSeries::new_str, 3))?;
785
819
  class.define_singleton_method("new_binary", function!(RbSeries::new_binary, 3))?;
@@ -836,7 +870,8 @@ fn init(ruby: &Ruby) -> RbResult<()> {
836
870
  class.define_method("div", method!(RbSeries::div, 1))?;
837
871
  class.define_method("rem", method!(RbSeries::rem, 1))?;
838
872
  class.define_method("sort", method!(RbSeries::sort, 3))?;
839
- class.define_method("value_counts", method!(RbSeries::value_counts, 1))?;
873
+ class.define_method("value_counts", method!(RbSeries::value_counts, 4))?;
874
+ class.define_method("slice", method!(RbSeries::slice, 2))?;
840
875
  class.define_method("any", method!(RbSeries::any, 1))?;
841
876
  class.define_method("all", method!(RbSeries::all, 1))?;
842
877
  class.define_method("arg_min", method!(RbSeries::arg_min, 0))?;
@@ -846,7 +881,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
846
881
  class.define_method("has_validity", method!(RbSeries::has_validity, 0))?;
847
882
  class.define_method("sample_n", method!(RbSeries::sample_n, 4))?;
848
883
  class.define_method("sample_frac", method!(RbSeries::sample_frac, 4))?;
849
- class.define_method("equals", method!(RbSeries::equals, 3))?;
884
+ class.define_method("equals", method!(RbSeries::equals, 4))?;
850
885
  class.define_method("eq", method!(RbSeries::eq, 1))?;
851
886
  class.define_method("neq", method!(RbSeries::neq, 1))?;
852
887
  class.define_method("gt", method!(RbSeries::gt, 1))?;
@@ -255,8 +255,8 @@ pub fn apply_lambda_with_rows_output<'a>(
255
255
  match RArray::try_convert(val).ok() {
256
256
  Some(tuple) => {
257
257
  row_buf.0.clear();
258
- for v in tuple.each() {
259
- let v = Wrap::<AnyValue>::try_convert(v.unwrap()).unwrap().0;
258
+ for v in tuple.into_iter() {
259
+ let v = Wrap::<AnyValue>::try_convert(v).unwrap().0;
260
260
  row_buf.0.push(v);
261
261
  }
262
262
  let ptr = &row_buf as *const Row;
@@ -8,31 +8,11 @@ pub fn binary_lambda(_lambda: Value, _a: Series, _b: Series) -> PolarsResult<Opt
8
8
  }
9
9
 
10
10
  pub fn map_single(
11
- rbexpr: &RbExpr,
11
+ _rbexpr: &RbExpr,
12
12
  _lambda: Value,
13
- output_type: Option<Wrap<DataType>>,
14
- agg_list: bool,
13
+ _output_type: Option<Wrap<DataType>>,
14
+ _agg_list: bool,
15
+ _is_elementwise: bool,
15
16
  ) -> RbExpr {
16
- let output_type = output_type.map(|wrap| wrap.0);
17
-
18
- let output_type2 = output_type.clone();
19
- let function = move |_s: Series| {
20
- let _output_type = output_type2.clone().unwrap_or(DataType::Unknown);
21
-
22
- todo!();
23
- };
24
-
25
- let output_map = GetOutput::map_field(move |fld| match output_type {
26
- Some(ref dt) => Field::new(fld.name(), dt.clone()),
27
- None => {
28
- let mut fld = fld.clone();
29
- fld.coerce(DataType::Unknown);
30
- fld
31
- }
32
- });
33
- if agg_list {
34
- rbexpr.clone().inner.map_list(function, output_map).into()
35
- } else {
36
- rbexpr.clone().inner.map(function, output_map).into()
37
- }
17
+ todo!();
38
18
  }
@@ -33,7 +33,12 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>(
33
33
  .apply_lambda_with_utf8_out_type(lambda, null_count, Some(first_value.as_str()))
34
34
  .map(|ca| ca.into_series().into())
35
35
  } else if out.respond_to("_s", true)? {
36
- todo!()
36
+ let rb_rbseries: &RbSeries = out.funcall("_s", ()).unwrap();
37
+ let series = rb_rbseries.series.borrow();
38
+ let dt = series.dtype();
39
+ applyer
40
+ .apply_lambda_with_list_out_type(lambda, null_count, &series, dt)
41
+ .map(|ca| ca.into_series().into())
37
42
  } else if out.is_kind_of(class::array()) {
38
43
  todo!()
39
44
  } else if out.is_kind_of(class::hash()) {
@@ -66,6 +71,7 @@ pub trait ApplyLambda<'a> {
66
71
  fn apply_lambda_unknown(&'a self, _lambda: Value) -> RbResult<RbSeries>;
67
72
 
68
73
  /// Apply a lambda that doesn't change output types
74
+ #[allow(dead_code)]
69
75
  fn apply_lambda(&'a self, _lambda: Value) -> RbResult<RbSeries>;
70
76
 
71
77
  // Used to store a struct type
@@ -1,4 +1,4 @@
1
- use magnus::{value::Lazy, Module, RClass, RModule, Ruby};
1
+ use magnus::{value::Lazy, ExceptionClass, Module, RClass, RModule, Ruby};
2
2
 
3
3
  static POLARS: Lazy<RModule> = Lazy::new(|ruby| ruby.class_object().const_get("Polars").unwrap());
4
4
 
@@ -38,3 +38,27 @@ static DATETIME: Lazy<RClass> =
38
38
  pub(crate) fn datetime() -> RClass {
39
39
  Ruby::get().unwrap().get_inner(&DATETIME)
40
40
  }
41
+
42
+ static ERROR: Lazy<ExceptionClass> =
43
+ Lazy::new(|ruby| ruby.get_inner(&POLARS).const_get("Error").unwrap());
44
+
45
+ pub(crate) fn error() -> ExceptionClass {
46
+ Ruby::get().unwrap().get_inner(&ERROR)
47
+ }
48
+
49
+ static COMPUTE_ERROR: Lazy<ExceptionClass> =
50
+ Lazy::new(|ruby| ruby.get_inner(&POLARS).const_get("ComputeError").unwrap());
51
+
52
+ pub(crate) fn compute_error() -> ExceptionClass {
53
+ Ruby::get().unwrap().get_inner(&COMPUTE_ERROR)
54
+ }
55
+
56
+ static INVALID_OPERATION_ERROR: Lazy<ExceptionClass> = Lazy::new(|ruby| {
57
+ ruby.get_inner(&POLARS)
58
+ .const_get("InvalidOperationError")
59
+ .unwrap()
60
+ });
61
+
62
+ pub(crate) fn invalid_operation_error() -> ExceptionClass {
63
+ Ruby::get().unwrap().get_inner(&INVALID_OPERATION_ERROR)
64
+ }
@@ -1,6 +1,6 @@
1
1
  use crate::error::RbPolarsErr;
2
2
  use crate::prelude::*;
3
- use crate::{RbResult, RbSeries, RbValueError};
3
+ use crate::{RbResult, RbSeries};
4
4
  use magnus::{IntoValue, Value};
5
5
 
6
6
  impl RbSeries {
@@ -36,31 +36,54 @@ impl RbSeries {
36
36
  Ok(Wrap(
37
37
  self.series
38
38
  .borrow()
39
- .max_as_series()
39
+ .max_reduce()
40
40
  .map_err(RbPolarsErr::from)?
41
- .get(0)
42
- .map_err(RbPolarsErr::from)?,
41
+ .as_any_value(),
43
42
  )
44
43
  .into_value())
45
44
  }
46
45
 
47
- pub fn mean(&self) -> Option<f64> {
46
+ pub fn mean(&self) -> RbResult<Value> {
48
47
  match self.series.borrow().dtype() {
49
- DataType::Boolean => {
50
- let s = self.series.borrow().cast(&DataType::UInt8).unwrap();
51
- s.mean()
48
+ DataType::Boolean => Ok(Wrap(
49
+ self.series
50
+ .borrow()
51
+ .cast(&DataType::UInt8)
52
+ .unwrap()
53
+ .mean_reduce()
54
+ .as_any_value(),
55
+ )
56
+ .into_value()),
57
+ // For non-numeric output types we require mean_reduce.
58
+ dt if dt.is_temporal() => {
59
+ Ok(Wrap(self.series.borrow().mean_reduce().as_any_value()).into_value())
52
60
  }
53
- _ => self.series.borrow().mean(),
61
+ _ => Ok(self.series.borrow().mean().into_value()),
54
62
  }
55
63
  }
56
64
 
57
- pub fn median(&self) -> Option<f64> {
65
+ pub fn median(&self) -> RbResult<Value> {
58
66
  match self.series.borrow().dtype() {
59
- DataType::Boolean => {
60
- let s = self.series.borrow().cast(&DataType::UInt8).unwrap();
61
- s.median()
62
- }
63
- _ => self.series.borrow().median(),
67
+ DataType::Boolean => Ok(Wrap(
68
+ self.series
69
+ .borrow()
70
+ .cast(&DataType::UInt8)
71
+ .unwrap()
72
+ .median_reduce()
73
+ .map_err(RbPolarsErr::from)?
74
+ .as_any_value(),
75
+ )
76
+ .into_value()),
77
+ // For non-numeric output types we require median_reduce.
78
+ dt if dt.is_temporal() => Ok(Wrap(
79
+ self.series
80
+ .borrow()
81
+ .median_reduce()
82
+ .map_err(RbPolarsErr::from)?
83
+ .as_any_value(),
84
+ )
85
+ .into_value()),
86
+ _ => Ok(self.series.borrow().median().into_value()),
64
87
  }
65
88
  }
66
89
 
@@ -68,10 +91,9 @@ impl RbSeries {
68
91
  Ok(Wrap(
69
92
  self.series
70
93
  .borrow()
71
- .min_as_series()
94
+ .min_reduce()
72
95
  .map_err(RbPolarsErr::from)?
73
- .get(0)
74
- .map_err(RbPolarsErr::from)?,
96
+ .as_any_value(),
75
97
  )
76
98
  .into_value())
77
99
  }
@@ -81,25 +103,22 @@ impl RbSeries {
81
103
  quantile: f64,
82
104
  interpolation: Wrap<QuantileInterpolOptions>,
83
105
  ) -> RbResult<Value> {
84
- Ok(Wrap(
85
- self.series
86
- .borrow()
87
- .quantile_as_series(quantile, interpolation.0)
88
- .map_err(|_| RbValueError::new_err("invalid quantile".into()))?
89
- .get(0)
90
- .unwrap_or(AnyValue::Null),
91
- )
92
- .into_value())
106
+ let bind = self
107
+ .series
108
+ .borrow()
109
+ .quantile_reduce(quantile, interpolation.0);
110
+ let sc = bind.map_err(RbPolarsErr::from)?;
111
+
112
+ Ok(Wrap(sc.as_any_value()).into_value())
93
113
  }
94
114
 
95
115
  pub fn sum(&self) -> RbResult<Value> {
96
116
  Ok(Wrap(
97
117
  self.series
98
118
  .borrow()
99
- .sum_as_series()
119
+ .sum_reduce()
100
120
  .map_err(RbPolarsErr::from)?
101
- .get(0)
102
- .map_err(RbPolarsErr::from)?,
121
+ .as_any_value(),
103
122
  )
104
123
  .into_value())
105
124
  }
@@ -1,24 +1,34 @@
1
- use crate::{RbResult, RbSeries};
1
+ use crate::{RbPolarsErr, RbResult, RbSeries};
2
2
 
3
3
  impl RbSeries {
4
- pub fn add(&self, other: &RbSeries) -> Self {
5
- (&*self.series.borrow() + &*other.series.borrow()).into()
4
+ pub fn add(&self, other: &RbSeries) -> RbResult<Self> {
5
+ (&*self.series.borrow() + &*other.series.borrow())
6
+ .map(Into::into)
7
+ .map_err(RbPolarsErr::from)
6
8
  }
7
9
 
8
- pub fn sub(&self, other: &RbSeries) -> Self {
9
- (&*self.series.borrow() - &*other.series.borrow()).into()
10
+ pub fn sub(&self, other: &RbSeries) -> RbResult<Self> {
11
+ (&*self.series.borrow() - &*other.series.borrow())
12
+ .map(Into::into)
13
+ .map_err(RbPolarsErr::from)
10
14
  }
11
15
 
12
- pub fn mul(&self, other: &RbSeries) -> Self {
13
- (&*self.series.borrow() * &*other.series.borrow()).into()
16
+ pub fn mul(&self, other: &RbSeries) -> RbResult<Self> {
17
+ (&*self.series.borrow() * &*other.series.borrow())
18
+ .map(Into::into)
19
+ .map_err(RbPolarsErr::from)
14
20
  }
15
21
 
16
- pub fn div(&self, other: &RbSeries) -> Self {
17
- (&*self.series.borrow() / &*other.series.borrow()).into()
22
+ pub fn div(&self, other: &RbSeries) -> RbResult<Self> {
23
+ (&*self.series.borrow() / &*other.series.borrow())
24
+ .map(Into::into)
25
+ .map_err(RbPolarsErr::from)
18
26
  }
19
27
 
20
- pub fn rem(&self, other: &RbSeries) -> Self {
21
- (&*self.series.borrow() % &*other.series.borrow()).into()
28
+ pub fn rem(&self, other: &RbSeries) -> RbResult<Self> {
29
+ (&*self.series.borrow() % &*other.series.borrow())
30
+ .map(Into::into)
31
+ .map_err(RbPolarsErr::from)
22
32
  }
23
33
  }
24
34