polars-df 0.8.0 → 0.10.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -1
- data/Cargo.lock +159 -66
- data/Cargo.toml +0 -3
- data/LICENSE.txt +1 -1
- data/README.md +3 -2
- data/ext/polars/Cargo.toml +18 -8
- data/ext/polars/src/batched_csv.rs +7 -5
- data/ext/polars/src/conversion/anyvalue.rs +186 -0
- data/ext/polars/src/conversion/chunked_array.rs +140 -0
- data/ext/polars/src/{conversion.rs → conversion/mod.rs} +273 -342
- data/ext/polars/src/dataframe.rs +108 -66
- data/ext/polars/src/expr/array.rs +78 -0
- data/ext/polars/src/expr/datetime.rs +29 -58
- data/ext/polars/src/expr/general.rs +83 -36
- data/ext/polars/src/expr/list.rs +58 -6
- data/ext/polars/src/expr/meta.rs +48 -0
- data/ext/polars/src/expr/rolling.rs +1 -0
- data/ext/polars/src/expr/string.rs +62 -11
- data/ext/polars/src/expr/struct.rs +8 -4
- data/ext/polars/src/file.rs +158 -11
- data/ext/polars/src/functions/aggregation.rs +6 -0
- data/ext/polars/src/functions/lazy.rs +120 -50
- data/ext/polars/src/functions/meta.rs +45 -1
- data/ext/polars/src/functions/string_cache.rs +14 -0
- data/ext/polars/src/functions/whenthen.rs +47 -17
- data/ext/polars/src/{lazyframe.rs → lazyframe/mod.rs} +195 -40
- data/ext/polars/src/lib.rs +246 -179
- data/ext/polars/src/map/dataframe.rs +17 -9
- data/ext/polars/src/series/aggregation.rs +20 -0
- data/ext/polars/src/series/mod.rs +35 -4
- data/lib/polars/array_expr.rb +453 -0
- data/lib/polars/array_name_space.rb +346 -0
- data/lib/polars/batched_csv_reader.rb +4 -2
- data/lib/polars/cat_expr.rb +24 -0
- data/lib/polars/cat_name_space.rb +75 -0
- data/lib/polars/config.rb +2 -2
- data/lib/polars/data_frame.rb +306 -96
- data/lib/polars/data_types.rb +191 -28
- data/lib/polars/date_time_expr.rb +41 -18
- data/lib/polars/date_time_name_space.rb +9 -3
- data/lib/polars/exceptions.rb +12 -1
- data/lib/polars/expr.rb +898 -215
- data/lib/polars/functions/aggregation/horizontal.rb +246 -0
- data/lib/polars/functions/aggregation/vertical.rb +282 -0
- data/lib/polars/functions/as_datatype.rb +248 -0
- data/lib/polars/functions/col.rb +47 -0
- data/lib/polars/functions/eager.rb +182 -0
- data/lib/polars/functions/lazy.rb +1280 -0
- data/lib/polars/functions/len.rb +49 -0
- data/lib/polars/functions/lit.rb +35 -0
- data/lib/polars/functions/random.rb +16 -0
- data/lib/polars/functions/range/date_range.rb +103 -0
- data/lib/polars/functions/range/int_range.rb +51 -0
- data/lib/polars/functions/repeat.rb +144 -0
- data/lib/polars/functions/whenthen.rb +96 -0
- data/lib/polars/functions.rb +29 -416
- data/lib/polars/group_by.rb +2 -2
- data/lib/polars/io.rb +36 -31
- data/lib/polars/lazy_frame.rb +405 -88
- data/lib/polars/list_expr.rb +158 -8
- data/lib/polars/list_name_space.rb +102 -0
- data/lib/polars/meta_expr.rb +175 -7
- data/lib/polars/series.rb +282 -41
- data/lib/polars/string_cache.rb +75 -0
- data/lib/polars/string_expr.rb +413 -96
- data/lib/polars/string_name_space.rb +4 -4
- data/lib/polars/testing.rb +507 -0
- data/lib/polars/utils.rb +106 -8
- data/lib/polars/version.rb +1 -1
- data/lib/polars/whenthen.rb +83 -0
- data/lib/polars.rb +16 -4
- metadata +37 -8
- data/lib/polars/lazy_functions.rb +0 -1181
- data/lib/polars/when.rb +0 -16
- data/lib/polars/when_then.rb +0 -19
data/ext/polars/src/dataframe.rs
CHANGED
@@ -6,16 +6,17 @@ use polars::frame::row::{rows_to_schema_supertypes, Row};
|
|
6
6
|
use polars::frame::NullStrategy;
|
7
7
|
use polars::io::avro::AvroCompression;
|
8
8
|
use polars::io::mmap::ReaderBytes;
|
9
|
-
use polars::io::
|
9
|
+
use polars::io::RowIndex;
|
10
10
|
use polars::prelude::pivot::{pivot, pivot_stable};
|
11
11
|
use polars::prelude::*;
|
12
12
|
use polars_core::utils::try_get_supertype;
|
13
13
|
use std::cell::RefCell;
|
14
14
|
use std::io::{BufWriter, Cursor};
|
15
|
+
use std::num::NonZeroUsize;
|
15
16
|
use std::ops::Deref;
|
16
17
|
|
17
18
|
use crate::conversion::*;
|
18
|
-
use crate::file::{get_file_like, get_mmap_bytes_reader};
|
19
|
+
use crate::file::{get_either_file, get_file_like, get_mmap_bytes_reader, EitherRustRubyFile};
|
19
20
|
use crate::map::dataframe::{
|
20
21
|
apply_lambda_unknown, apply_lambda_with_bool_out_type, apply_lambda_with_primitive_out_type,
|
21
22
|
apply_lambda_with_utf8_out_type,
|
@@ -45,44 +46,51 @@ impl RbDataFrame {
|
|
45
46
|
fn finish_from_rows(
|
46
47
|
rows: Vec<Row>,
|
47
48
|
infer_schema_length: Option<usize>,
|
48
|
-
|
49
|
+
schema: Option<Schema>,
|
50
|
+
schema_overrides_by_idx: Option<Vec<(usize, DataType)>>,
|
49
51
|
) -> RbResult<Self> {
|
50
|
-
//
|
52
|
+
// Object builder must be registered
|
51
53
|
crate::on_startup::register_object_builder();
|
52
54
|
|
53
|
-
let
|
55
|
+
let mut final_schema =
|
54
56
|
rows_to_schema_supertypes(&rows, infer_schema_length.map(|n| std::cmp::max(1, n)))
|
55
57
|
.map_err(RbPolarsErr::from)?;
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
}
|
62
|
-
DataType::Decimal(_, _) => {
|
63
|
-
fld.coerce(DataType::Decimal(None, None));
|
64
|
-
fld
|
58
|
+
|
59
|
+
// Erase scale from inferred decimals.
|
60
|
+
for dtype in final_schema.iter_dtypes_mut() {
|
61
|
+
if let DataType::Decimal(_, _) = dtype {
|
62
|
+
*dtype = DataType::Decimal(None, None)
|
65
63
|
}
|
66
|
-
|
67
|
-
});
|
68
|
-
let mut schema = Schema::from_iter(fields);
|
64
|
+
}
|
69
65
|
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
// Integrate explicit/inferred schema.
|
67
|
+
if let Some(schema) = schema {
|
68
|
+
for (i, (name, dtype)) in schema.into_iter().enumerate() {
|
69
|
+
if let Some((name_, dtype_)) = final_schema.get_at_index_mut(i) {
|
73
70
|
*name_ = name;
|
74
71
|
|
75
|
-
//
|
72
|
+
// If schema dtype is Unknown, overwrite with inferred datatype.
|
76
73
|
if !matches!(dtype, DataType::Unknown) {
|
77
74
|
*dtype_ = dtype;
|
78
75
|
}
|
79
76
|
} else {
|
80
|
-
|
77
|
+
final_schema.with_column(name, dtype);
|
81
78
|
}
|
82
79
|
}
|
83
80
|
}
|
84
81
|
|
85
|
-
|
82
|
+
// Optional per-field overrides; these supersede default/inferred dtypes.
|
83
|
+
if let Some(overrides) = schema_overrides_by_idx {
|
84
|
+
for (i, dtype) in overrides {
|
85
|
+
if let Some((_, dtype_)) = final_schema.get_at_index_mut(i) {
|
86
|
+
if !matches!(dtype, DataType::Unknown) {
|
87
|
+
*dtype_ = dtype;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
let df =
|
93
|
+
DataFrame::from_rows_and_schema(&rows, &final_schema).map_err(RbPolarsErr::from)?;
|
86
94
|
Ok(df.into())
|
87
95
|
}
|
88
96
|
|
@@ -125,15 +133,16 @@ impl RbDataFrame {
|
|
125
133
|
let null_values = Option::<Wrap<NullValues>>::try_convert(arguments[19])?;
|
126
134
|
let try_parse_dates = bool::try_convert(arguments[20])?;
|
127
135
|
let skip_rows_after_header = usize::try_convert(arguments[21])?;
|
128
|
-
let
|
136
|
+
let row_index = Option::<(String, IdxSize)>::try_convert(arguments[22])?;
|
129
137
|
let sample_size = usize::try_convert(arguments[23])?;
|
130
138
|
let eol_char = String::try_convert(arguments[24])?;
|
139
|
+
let truncate_ragged_lines = bool::try_convert(arguments[25])?;
|
131
140
|
// end arguments
|
132
141
|
|
133
142
|
let null_values = null_values.map(|w| w.0);
|
134
143
|
let eol_char = eol_char.as_bytes()[0];
|
135
144
|
|
136
|
-
let
|
145
|
+
let row_index = row_index.map(|(name, offset)| RowIndex { name, offset });
|
137
146
|
|
138
147
|
let quote_char = if let Some(s) = quote_char {
|
139
148
|
if s.is_empty() {
|
@@ -186,8 +195,9 @@ impl RbDataFrame {
|
|
186
195
|
.with_quote_char(quote_char)
|
187
196
|
.with_end_of_line_char(eol_char)
|
188
197
|
.with_skip_rows_after_header(skip_rows_after_header)
|
189
|
-
.
|
198
|
+
.with_row_index(row_index)
|
190
199
|
.sample_size(sample_size)
|
200
|
+
.truncate_ragged_lines(truncate_ragged_lines)
|
191
201
|
.finish()
|
192
202
|
.map_err(RbPolarsErr::from)?;
|
193
203
|
Ok(df.into())
|
@@ -200,24 +210,39 @@ impl RbDataFrame {
|
|
200
210
|
projection: Option<Vec<usize>>,
|
201
211
|
n_rows: Option<usize>,
|
202
212
|
parallel: Wrap<ParallelStrategy>,
|
203
|
-
|
213
|
+
row_index: Option<(String, IdxSize)>,
|
204
214
|
low_memory: bool,
|
205
215
|
use_statistics: bool,
|
206
216
|
rechunk: bool,
|
207
217
|
) -> RbResult<Self> {
|
208
|
-
|
209
|
-
|
210
|
-
let
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
218
|
+
use EitherRustRubyFile::*;
|
219
|
+
|
220
|
+
let row_index = row_index.map(|(name, offset)| RowIndex { name, offset });
|
221
|
+
let result = match get_either_file(rb_f, false)? {
|
222
|
+
Rb(f) => {
|
223
|
+
let buf = f.as_buffer();
|
224
|
+
ParquetReader::new(buf)
|
225
|
+
.with_projection(projection)
|
226
|
+
.with_columns(columns)
|
227
|
+
.read_parallel(parallel.0)
|
228
|
+
.with_n_rows(n_rows)
|
229
|
+
.with_row_index(row_index)
|
230
|
+
.set_low_memory(low_memory)
|
231
|
+
.use_statistics(use_statistics)
|
232
|
+
.set_rechunk(rechunk)
|
233
|
+
.finish()
|
234
|
+
}
|
235
|
+
Rust(f) => ParquetReader::new(f.into_inner())
|
236
|
+
.with_projection(projection)
|
237
|
+
.with_columns(columns)
|
238
|
+
.read_parallel(parallel.0)
|
239
|
+
.with_n_rows(n_rows)
|
240
|
+
.with_row_index(row_index)
|
241
|
+
.use_statistics(use_statistics)
|
242
|
+
.set_rechunk(rechunk)
|
243
|
+
.finish(),
|
244
|
+
};
|
245
|
+
let df = result.map_err(RbPolarsErr::from)?;
|
221
246
|
Ok(RbDataFrame::new(df))
|
222
247
|
}
|
223
248
|
|
@@ -226,16 +251,16 @@ impl RbDataFrame {
|
|
226
251
|
columns: Option<Vec<String>>,
|
227
252
|
projection: Option<Vec<usize>>,
|
228
253
|
n_rows: Option<usize>,
|
229
|
-
|
254
|
+
row_index: Option<(String, IdxSize)>,
|
230
255
|
memory_map: bool,
|
231
256
|
) -> RbResult<Self> {
|
232
|
-
let
|
257
|
+
let row_index = row_index.map(|(name, offset)| RowIndex { name, offset });
|
233
258
|
let mmap_bytes_r = get_mmap_bytes_reader(rb_f)?;
|
234
259
|
let df = IpcReader::new(mmap_bytes_r)
|
235
260
|
.with_projection(projection)
|
236
261
|
.with_columns(columns)
|
237
262
|
.with_n_rows(n_rows)
|
238
|
-
.
|
263
|
+
.with_row_index(row_index)
|
239
264
|
.memory_mapped(memory_map)
|
240
265
|
.finish()
|
241
266
|
.map_err(RbPolarsErr::from)?;
|
@@ -352,7 +377,7 @@ impl RbDataFrame {
|
|
352
377
|
pub fn read_rows(
|
353
378
|
rb_rows: RArray,
|
354
379
|
infer_schema_length: Option<usize>,
|
355
|
-
|
380
|
+
schema: Option<Wrap<Schema>>,
|
356
381
|
) -> RbResult<Self> {
|
357
382
|
let mut rows = Vec::with_capacity(rb_rows.len());
|
358
383
|
for v in rb_rows.each() {
|
@@ -363,30 +388,34 @@ impl RbDataFrame {
|
|
363
388
|
}
|
364
389
|
rows.push(Row(row));
|
365
390
|
}
|
366
|
-
Self::finish_from_rows(
|
367
|
-
rows,
|
368
|
-
infer_schema_length,
|
369
|
-
schema_overwrite.map(|wrap| wrap.0),
|
370
|
-
)
|
391
|
+
Self::finish_from_rows(rows, infer_schema_length, schema.map(|wrap| wrap.0), None)
|
371
392
|
}
|
372
393
|
|
373
394
|
pub fn read_hashes(
|
374
395
|
dicts: Value,
|
375
396
|
infer_schema_length: Option<usize>,
|
376
|
-
|
397
|
+
schema: Option<Wrap<Schema>>,
|
398
|
+
schema_overrides: Option<Wrap<Schema>>,
|
377
399
|
) -> RbResult<Self> {
|
378
|
-
let
|
400
|
+
let mut schema_columns = PlIndexSet::new();
|
401
|
+
if let Some(s) = &schema {
|
402
|
+
schema_columns.extend(s.0.iter_names().map(|n| n.to_string()))
|
403
|
+
}
|
404
|
+
let (rows, names) = dicts_to_rows(&dicts, infer_schema_length, schema_columns)?;
|
379
405
|
|
380
|
-
|
381
|
-
if let Some(
|
382
|
-
for (
|
383
|
-
|
406
|
+
let mut schema_overrides_by_idx: Vec<(usize, DataType)> = Vec::new();
|
407
|
+
if let Some(overrides) = schema_overrides {
|
408
|
+
for (idx, name) in names.iter().enumerate() {
|
409
|
+
if let Some(dtype) = overrides.0.get(name) {
|
410
|
+
schema_overrides_by_idx.push((idx, dtype.clone()));
|
411
|
+
}
|
384
412
|
}
|
385
413
|
}
|
386
414
|
let rbdf = Self::finish_from_rows(
|
387
415
|
rows,
|
388
416
|
infer_schema_length,
|
389
|
-
|
417
|
+
schema.map(|wrap| wrap.0),
|
418
|
+
Some(schema_overrides_by_idx),
|
390
419
|
)?;
|
391
420
|
|
392
421
|
unsafe {
|
@@ -427,13 +456,14 @@ impl RbDataFrame {
|
|
427
456
|
include_header: bool,
|
428
457
|
separator: u8,
|
429
458
|
quote_char: u8,
|
430
|
-
batch_size:
|
459
|
+
batch_size: Wrap<NonZeroUsize>,
|
431
460
|
datetime_format: Option<String>,
|
432
461
|
date_format: Option<String>,
|
433
462
|
time_format: Option<String>,
|
434
463
|
float_precision: Option<usize>,
|
435
464
|
null_value: Option<String>,
|
436
465
|
) -> RbResult<()> {
|
466
|
+
let batch_size = batch_size.0;
|
437
467
|
let null = null_value.unwrap_or_default();
|
438
468
|
|
439
469
|
if let Ok(s) = String::try_convert(rb_f) {
|
@@ -563,6 +593,7 @@ impl RbDataFrame {
|
|
563
593
|
compression_level: Option<i32>,
|
564
594
|
statistics: bool,
|
565
595
|
row_group_size: Option<usize>,
|
596
|
+
data_page_size: Option<usize>,
|
566
597
|
) -> RbResult<()> {
|
567
598
|
let compression = parse_parquet_compression(&compression, compression_level)?;
|
568
599
|
|
@@ -572,10 +603,18 @@ impl RbDataFrame {
|
|
572
603
|
.with_compression(compression)
|
573
604
|
.with_statistics(statistics)
|
574
605
|
.with_row_group_size(row_group_size)
|
606
|
+
.with_data_page_size(data_page_size)
|
575
607
|
.finish(&mut self.df.borrow_mut())
|
576
608
|
.map_err(RbPolarsErr::from)?;
|
577
609
|
} else {
|
578
|
-
|
610
|
+
let buf = get_file_like(rb_f, true)?;
|
611
|
+
ParquetWriter::new(buf)
|
612
|
+
.with_compression(compression)
|
613
|
+
.with_statistics(statistics)
|
614
|
+
.with_row_group_size(row_group_size)
|
615
|
+
.with_data_page_size(data_page_size)
|
616
|
+
.finish(&mut self.df.borrow_mut())
|
617
|
+
.map_err(RbPolarsErr::from)?;
|
579
618
|
}
|
580
619
|
|
581
620
|
Ok(())
|
@@ -794,12 +833,11 @@ impl RbDataFrame {
|
|
794
833
|
self.df.borrow().get_column_index(&name)
|
795
834
|
}
|
796
835
|
|
797
|
-
|
798
|
-
pub fn column(&self, name: String) -> RbResult<RbSeries> {
|
836
|
+
pub fn get_column(&self, name: String) -> RbResult<RbSeries> {
|
799
837
|
self.df
|
800
838
|
.borrow()
|
801
839
|
.column(&name)
|
802
|
-
.map(|
|
840
|
+
.map(|s| RbSeries::new(s.clone()))
|
803
841
|
.map_err(RbPolarsErr::from)
|
804
842
|
}
|
805
843
|
|
@@ -887,11 +925,11 @@ impl RbDataFrame {
|
|
887
925
|
}
|
888
926
|
}
|
889
927
|
|
890
|
-
pub fn
|
928
|
+
pub fn with_row_index(&self, name: String, offset: Option<IdxSize>) -> RbResult<Self> {
|
891
929
|
let df = self
|
892
930
|
.df
|
893
931
|
.borrow()
|
894
|
-
.
|
932
|
+
.with_row_index(&name, offset)
|
895
933
|
.map_err(RbPolarsErr::from)?;
|
896
934
|
Ok(df.into())
|
897
935
|
}
|
@@ -922,9 +960,9 @@ impl RbDataFrame {
|
|
922
960
|
#[allow(clippy::too_many_arguments)]
|
923
961
|
pub fn pivot_expr(
|
924
962
|
&self,
|
925
|
-
values: Vec<String>,
|
926
963
|
index: Vec<String>,
|
927
964
|
columns: Vec<String>,
|
965
|
+
values: Option<Vec<String>>,
|
928
966
|
maintain_order: bool,
|
929
967
|
sort_columns: bool,
|
930
968
|
aggregate_expr: Option<&RbExpr>,
|
@@ -937,9 +975,9 @@ impl RbDataFrame {
|
|
937
975
|
let agg_expr = aggregate_expr.map(|aggregate_expr| aggregate_expr.inner.clone());
|
938
976
|
let df = fun(
|
939
977
|
&self.df.borrow(),
|
940
|
-
values,
|
941
978
|
index,
|
942
979
|
columns,
|
980
|
+
values,
|
943
981
|
sort_columns,
|
944
982
|
agg_expr,
|
945
983
|
separator.as_deref(),
|
@@ -1121,7 +1159,7 @@ impl RbDataFrame {
|
|
1121
1159
|
};
|
1122
1160
|
Ok(self
|
1123
1161
|
.df
|
1124
|
-
.
|
1162
|
+
.borrow_mut()
|
1125
1163
|
.transpose(keep_names_as.as_deref(), new_col_names)
|
1126
1164
|
.map_err(RbPolarsErr::from)?
|
1127
1165
|
.into())
|
@@ -1163,4 +1201,8 @@ impl RbDataFrame {
|
|
1163
1201
|
let df = self.df.borrow().unnest(names).map_err(RbPolarsErr::from)?;
|
1164
1202
|
Ok(df.into())
|
1165
1203
|
}
|
1204
|
+
|
1205
|
+
pub fn clear(&self) -> Self {
|
1206
|
+
self.df.borrow().clear().into()
|
1207
|
+
}
|
1166
1208
|
}
|
@@ -1,3 +1,5 @@
|
|
1
|
+
use polars::prelude::*;
|
2
|
+
|
1
3
|
use crate::RbExpr;
|
2
4
|
|
3
5
|
impl RbExpr {
|
@@ -12,4 +14,80 @@ impl RbExpr {
|
|
12
14
|
pub fn array_sum(&self) -> Self {
|
13
15
|
self.inner.clone().arr().sum().into()
|
14
16
|
}
|
17
|
+
|
18
|
+
pub fn arr_unique(&self, maintain_order: bool) -> Self {
|
19
|
+
if maintain_order {
|
20
|
+
self.inner.clone().arr().unique_stable().into()
|
21
|
+
} else {
|
22
|
+
self.inner.clone().arr().unique().into()
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
pub fn arr_to_list(&self) -> Self {
|
27
|
+
self.inner.clone().arr().to_list().into()
|
28
|
+
}
|
29
|
+
|
30
|
+
pub fn arr_all(&self) -> Self {
|
31
|
+
self.inner.clone().arr().all().into()
|
32
|
+
}
|
33
|
+
|
34
|
+
pub fn arr_any(&self) -> Self {
|
35
|
+
self.inner.clone().arr().any().into()
|
36
|
+
}
|
37
|
+
|
38
|
+
pub fn arr_sort(&self, descending: bool, nulls_last: bool) -> Self {
|
39
|
+
self.inner
|
40
|
+
.clone()
|
41
|
+
.arr()
|
42
|
+
.sort(SortOptions {
|
43
|
+
descending,
|
44
|
+
nulls_last,
|
45
|
+
..Default::default()
|
46
|
+
})
|
47
|
+
.into()
|
48
|
+
}
|
49
|
+
|
50
|
+
pub fn arr_reverse(&self) -> Self {
|
51
|
+
self.inner.clone().arr().reverse().into()
|
52
|
+
}
|
53
|
+
|
54
|
+
pub fn arr_arg_min(&self) -> Self {
|
55
|
+
self.inner.clone().arr().arg_min().into()
|
56
|
+
}
|
57
|
+
|
58
|
+
pub fn arr_arg_max(&self) -> Self {
|
59
|
+
self.inner.clone().arr().arg_max().into()
|
60
|
+
}
|
61
|
+
|
62
|
+
pub fn arr_get(&self, index: &RbExpr, null_on_oob: bool) -> Self {
|
63
|
+
self.inner
|
64
|
+
.clone()
|
65
|
+
.arr()
|
66
|
+
.get(index.inner.clone(), null_on_oob)
|
67
|
+
.into()
|
68
|
+
}
|
69
|
+
|
70
|
+
pub fn arr_join(&self, separator: &RbExpr, ignore_nulls: bool) -> Self {
|
71
|
+
self.inner
|
72
|
+
.clone()
|
73
|
+
.arr()
|
74
|
+
.join(separator.inner.clone(), ignore_nulls)
|
75
|
+
.into()
|
76
|
+
}
|
77
|
+
|
78
|
+
pub fn arr_contains(&self, other: &RbExpr) -> Self {
|
79
|
+
self.inner
|
80
|
+
.clone()
|
81
|
+
.arr()
|
82
|
+
.contains(other.inner.clone())
|
83
|
+
.into()
|
84
|
+
}
|
85
|
+
|
86
|
+
pub fn arr_count_matches(&self, expr: &RbExpr) -> Self {
|
87
|
+
self.inner
|
88
|
+
.clone()
|
89
|
+
.arr()
|
90
|
+
.count_matches(expr.inner.clone())
|
91
|
+
.into()
|
92
|
+
}
|
15
93
|
}
|
@@ -37,11 +37,16 @@ impl RbExpr {
|
|
37
37
|
self.inner.clone().dt().cast_time_unit(tu.0).into()
|
38
38
|
}
|
39
39
|
|
40
|
-
pub fn dt_replace_time_zone(
|
40
|
+
pub fn dt_replace_time_zone(
|
41
|
+
&self,
|
42
|
+
time_zone: Option<String>,
|
43
|
+
ambiguous: &Self,
|
44
|
+
non_existent: Wrap<NonExistent>,
|
45
|
+
) -> Self {
|
41
46
|
self.inner
|
42
47
|
.clone()
|
43
48
|
.dt()
|
44
|
-
.replace_time_zone(time_zone, ambiguous.inner.clone())
|
49
|
+
.replace_time_zone(time_zone, ambiguous.inner.clone(), non_existent.0)
|
45
50
|
.into()
|
46
51
|
}
|
47
52
|
|
@@ -61,6 +66,14 @@ impl RbExpr {
|
|
61
66
|
self.inner.clone().dt().month_end().into()
|
62
67
|
}
|
63
68
|
|
69
|
+
pub fn dt_base_utc_offset(&self) -> Self {
|
70
|
+
self.inner.clone().dt().base_utc_offset().into()
|
71
|
+
}
|
72
|
+
|
73
|
+
pub fn dt_dst_offset(&self) -> Self {
|
74
|
+
self.inner.clone().dt().dst_offset().into()
|
75
|
+
}
|
76
|
+
|
64
77
|
pub fn dt_round(&self, every: String, offset: String) -> Self {
|
65
78
|
self.inner.clone().dt().round(&every, &offset).into()
|
66
79
|
}
|
@@ -149,73 +162,31 @@ impl RbExpr {
|
|
149
162
|
self.inner.clone().dt().timestamp(tu.0).into()
|
150
163
|
}
|
151
164
|
|
152
|
-
pub fn
|
153
|
-
self.inner
|
154
|
-
.clone()
|
155
|
-
.map(
|
156
|
-
|s| Ok(Some(s.duration()?.days().into_series())),
|
157
|
-
GetOutput::from_type(DataType::Int64),
|
158
|
-
)
|
159
|
-
.into()
|
165
|
+
pub fn dt_total_days(&self) -> Self {
|
166
|
+
self.inner.clone().dt().total_days().into()
|
160
167
|
}
|
161
168
|
|
162
|
-
pub fn
|
163
|
-
self.inner
|
164
|
-
.clone()
|
165
|
-
.map(
|
166
|
-
|s| Ok(Some(s.duration()?.hours().into_series())),
|
167
|
-
GetOutput::from_type(DataType::Int64),
|
168
|
-
)
|
169
|
-
.into()
|
169
|
+
pub fn dt_total_hours(&self) -> Self {
|
170
|
+
self.inner.clone().dt().total_hours().into()
|
170
171
|
}
|
171
172
|
|
172
|
-
pub fn
|
173
|
-
self.inner
|
174
|
-
.clone()
|
175
|
-
.map(
|
176
|
-
|s| Ok(Some(s.duration()?.minutes().into_series())),
|
177
|
-
GetOutput::from_type(DataType::Int64),
|
178
|
-
)
|
179
|
-
.into()
|
173
|
+
pub fn dt_total_minutes(&self) -> Self {
|
174
|
+
self.inner.clone().dt().total_minutes().into()
|
180
175
|
}
|
181
176
|
|
182
|
-
pub fn
|
183
|
-
self.inner
|
184
|
-
.clone()
|
185
|
-
.map(
|
186
|
-
|s| Ok(Some(s.duration()?.seconds().into_series())),
|
187
|
-
GetOutput::from_type(DataType::Int64),
|
188
|
-
)
|
189
|
-
.into()
|
177
|
+
pub fn dt_total_seconds(&self) -> Self {
|
178
|
+
self.inner.clone().dt().total_seconds().into()
|
190
179
|
}
|
191
180
|
|
192
|
-
pub fn
|
193
|
-
self.inner
|
194
|
-
.clone()
|
195
|
-
.map(
|
196
|
-
|s| Ok(Some(s.duration()?.milliseconds().into_series())),
|
197
|
-
GetOutput::from_type(DataType::Int64),
|
198
|
-
)
|
199
|
-
.into()
|
181
|
+
pub fn dt_total_milliseconds(&self) -> Self {
|
182
|
+
self.inner.clone().dt().total_milliseconds().into()
|
200
183
|
}
|
201
184
|
|
202
|
-
pub fn
|
203
|
-
self.inner
|
204
|
-
.clone()
|
205
|
-
.map(
|
206
|
-
|s| Ok(Some(s.duration()?.microseconds().into_series())),
|
207
|
-
GetOutput::from_type(DataType::Int64),
|
208
|
-
)
|
209
|
-
.into()
|
185
|
+
pub fn dt_total_microseconds(&self) -> Self {
|
186
|
+
self.inner.clone().dt().total_microseconds().into()
|
210
187
|
}
|
211
188
|
|
212
|
-
pub fn
|
213
|
-
self.inner
|
214
|
-
.clone()
|
215
|
-
.map(
|
216
|
-
|s| Ok(Some(s.duration()?.nanoseconds().into_series())),
|
217
|
-
GetOutput::from_type(DataType::Int64),
|
218
|
-
)
|
219
|
-
.into()
|
189
|
+
pub fn dt_total_nanoseconds(&self) -> Self {
|
190
|
+
self.inner.clone().dt().total_nanoseconds().into()
|
220
191
|
}
|
221
192
|
}
|