polars-df 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Cargo.lock +90 -48
  4. data/README.md +6 -6
  5. data/ext/polars/Cargo.toml +7 -5
  6. data/ext/polars/src/batched_csv.rs +53 -52
  7. data/ext/polars/src/conversion/mod.rs +13 -60
  8. data/ext/polars/src/dataframe/construction.rs +186 -0
  9. data/ext/polars/src/dataframe/export.rs +48 -0
  10. data/ext/polars/src/dataframe/general.rs +607 -0
  11. data/ext/polars/src/dataframe/io.rs +463 -0
  12. data/ext/polars/src/dataframe/mod.rs +26 -0
  13. data/ext/polars/src/expr/datetime.rs +6 -2
  14. data/ext/polars/src/expr/general.rs +28 -6
  15. data/ext/polars/src/expr/rolling.rs +185 -69
  16. data/ext/polars/src/expr/string.rs +9 -30
  17. data/ext/polars/src/functions/lazy.rs +2 -0
  18. data/ext/polars/src/functions/range.rs +74 -0
  19. data/ext/polars/src/interop/mod.rs +1 -0
  20. data/ext/polars/src/interop/numo/mod.rs +2 -0
  21. data/ext/polars/src/interop/numo/to_numo_df.rs +23 -0
  22. data/ext/polars/src/interop/numo/to_numo_series.rs +60 -0
  23. data/ext/polars/src/lazyframe/mod.rs +54 -38
  24. data/ext/polars/src/lib.rs +46 -21
  25. data/ext/polars/src/map/lazy.rs +5 -25
  26. data/ext/polars/src/map/series.rs +7 -1
  27. data/ext/polars/src/series/aggregation.rs +47 -30
  28. data/ext/polars/src/series/export.rs +131 -49
  29. data/ext/polars/src/series/mod.rs +1 -131
  30. data/lib/polars/batched_csv_reader.rb +9 -3
  31. data/lib/polars/convert.rb +6 -1
  32. data/lib/polars/data_frame.rb +83 -302
  33. data/lib/polars/date_time_expr.rb +1 -0
  34. data/lib/polars/date_time_name_space.rb +5 -1
  35. data/lib/polars/dynamic_group_by.rb +2 -2
  36. data/lib/polars/exceptions.rb +4 -0
  37. data/lib/polars/expr.rb +1134 -20
  38. data/lib/polars/functions/range/date_range.rb +92 -0
  39. data/lib/polars/functions/range/datetime_range.rb +149 -0
  40. data/lib/polars/functions/range/time_range.rb +141 -0
  41. data/lib/polars/group_by.rb +88 -23
  42. data/lib/polars/io/avro.rb +24 -0
  43. data/lib/polars/{io.rb → io/csv.rb} +296 -490
  44. data/lib/polars/io/database.rb +73 -0
  45. data/lib/polars/io/ipc.rb +247 -0
  46. data/lib/polars/io/json.rb +18 -0
  47. data/lib/polars/io/ndjson.rb +69 -0
  48. data/lib/polars/io/parquet.rb +226 -0
  49. data/lib/polars/lazy_frame.rb +23 -166
  50. data/lib/polars/lazy_group_by.rb +100 -3
  51. data/lib/polars/rolling_group_by.rb +2 -2
  52. data/lib/polars/series.rb +2 -2
  53. data/lib/polars/string_expr.rb +37 -36
  54. data/lib/polars/utils.rb +35 -1
  55. data/lib/polars/version.rb +1 -1
  56. data/lib/polars.rb +9 -1
  57. metadata +21 -5
  58. data/ext/polars/src/dataframe.rs +0 -1208
@@ -1,1208 +0,0 @@
1
- use either::Either;
2
- use magnus::{
3
- prelude::*, r_hash::ForEach, typed_data::Obj, IntoValue, RArray, RHash, RString, Value,
4
- };
5
- use polars::frame::row::{rows_to_schema_supertypes, Row};
6
- use polars::frame::NullStrategy;
7
- use polars::io::avro::AvroCompression;
8
- use polars::io::mmap::ReaderBytes;
9
- use polars::io::RowIndex;
10
- use polars::prelude::pivot::{pivot, pivot_stable};
11
- use polars::prelude::*;
12
- use polars_core::utils::try_get_supertype;
13
- use std::cell::RefCell;
14
- use std::io::{BufWriter, Cursor};
15
- use std::num::NonZeroUsize;
16
- use std::ops::Deref;
17
-
18
- use crate::conversion::*;
19
- use crate::file::{get_either_file, get_file_like, get_mmap_bytes_reader, EitherRustRubyFile};
20
- use crate::map::dataframe::{
21
- apply_lambda_unknown, apply_lambda_with_bool_out_type, apply_lambda_with_primitive_out_type,
22
- apply_lambda_with_utf8_out_type,
23
- };
24
- use crate::rb_modules;
25
- use crate::series::{to_rbseries_collection, to_series_collection};
26
- use crate::{RbExpr, RbLazyFrame, RbPolarsErr, RbResult, RbSeries};
27
-
28
- #[magnus::wrap(class = "Polars::RbDataFrame")]
29
- pub struct RbDataFrame {
30
- pub df: RefCell<DataFrame>,
31
- }
32
-
33
- impl From<DataFrame> for RbDataFrame {
34
- fn from(df: DataFrame) -> Self {
35
- RbDataFrame::new(df)
36
- }
37
- }
38
-
39
- impl RbDataFrame {
40
- pub fn new(df: DataFrame) -> Self {
41
- RbDataFrame {
42
- df: RefCell::new(df),
43
- }
44
- }
45
-
46
- fn finish_from_rows(
47
- rows: Vec<Row>,
48
- infer_schema_length: Option<usize>,
49
- schema: Option<Schema>,
50
- schema_overrides_by_idx: Option<Vec<(usize, DataType)>>,
51
- ) -> RbResult<Self> {
52
- // Object builder must be registered
53
- crate::on_startup::register_object_builder();
54
-
55
- let mut final_schema =
56
- rows_to_schema_supertypes(&rows, infer_schema_length.map(|n| std::cmp::max(1, n)))
57
- .map_err(RbPolarsErr::from)?;
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)
63
- }
64
- }
65
-
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) {
70
- *name_ = name;
71
-
72
- // If schema dtype is Unknown, overwrite with inferred datatype.
73
- if !matches!(dtype, DataType::Unknown) {
74
- *dtype_ = dtype;
75
- }
76
- } else {
77
- final_schema.with_column(name, dtype);
78
- }
79
- }
80
- }
81
-
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)?;
94
- Ok(df.into())
95
- }
96
-
97
- pub fn init(columns: RArray) -> RbResult<Self> {
98
- let mut cols = Vec::new();
99
- for i in columns.each() {
100
- cols.push(<&RbSeries>::try_convert(i?)?.series.borrow().clone());
101
- }
102
- let df = DataFrame::new(cols).map_err(RbPolarsErr::from)?;
103
- Ok(RbDataFrame::new(df))
104
- }
105
-
106
- pub fn estimated_size(&self) -> usize {
107
- self.df.borrow().estimated_size()
108
- }
109
-
110
- pub fn read_csv(arguments: &[Value]) -> RbResult<Self> {
111
- // start arguments
112
- // this pattern is needed for more than 16
113
- let rb_f = arguments[0];
114
- let infer_schema_length = Option::<usize>::try_convert(arguments[1])?;
115
- let chunk_size = usize::try_convert(arguments[2])?;
116
- let has_header = bool::try_convert(arguments[3])?;
117
- let ignore_errors = bool::try_convert(arguments[4])?;
118
- let n_rows = Option::<usize>::try_convert(arguments[5])?;
119
- let skip_rows = usize::try_convert(arguments[6])?;
120
- let projection = Option::<Vec<usize>>::try_convert(arguments[7])?;
121
- let separator = String::try_convert(arguments[8])?;
122
- let rechunk = bool::try_convert(arguments[9])?;
123
- let columns = Option::<Vec<String>>::try_convert(arguments[10])?;
124
- let encoding = Wrap::<CsvEncoding>::try_convert(arguments[11])?;
125
- let n_threads = Option::<usize>::try_convert(arguments[12])?;
126
- let path = Option::<String>::try_convert(arguments[13])?;
127
- let overwrite_dtype = Option::<Vec<(String, Wrap<DataType>)>>::try_convert(arguments[14])?;
128
- // TODO fix
129
- let overwrite_dtype_slice = Option::<Vec<Wrap<DataType>>>::None; // Option::<Vec<Wrap<DataType>>>::try_convert(arguments[15])?;
130
- let low_memory = bool::try_convert(arguments[16])?;
131
- let comment_prefix = Option::<String>::try_convert(arguments[17])?;
132
- let quote_char = Option::<String>::try_convert(arguments[18])?;
133
- let null_values = Option::<Wrap<NullValues>>::try_convert(arguments[19])?;
134
- let try_parse_dates = bool::try_convert(arguments[20])?;
135
- let skip_rows_after_header = usize::try_convert(arguments[21])?;
136
- let row_index = Option::<(String, IdxSize)>::try_convert(arguments[22])?;
137
- let sample_size = usize::try_convert(arguments[23])?;
138
- let eol_char = String::try_convert(arguments[24])?;
139
- let truncate_ragged_lines = bool::try_convert(arguments[25])?;
140
- // end arguments
141
-
142
- let null_values = null_values.map(|w| w.0);
143
- let eol_char = eol_char.as_bytes()[0];
144
-
145
- let row_index = row_index.map(|(name, offset)| RowIndex { name, offset });
146
-
147
- let quote_char = if let Some(s) = quote_char {
148
- if s.is_empty() {
149
- None
150
- } else {
151
- Some(s.as_bytes()[0])
152
- }
153
- } else {
154
- None
155
- };
156
-
157
- let overwrite_dtype = overwrite_dtype.map(|overwrite_dtype| {
158
- overwrite_dtype
159
- .iter()
160
- .map(|(name, dtype)| {
161
- let dtype = dtype.0.clone();
162
- Field::new(name, dtype)
163
- })
164
- .collect::<Schema>()
165
- });
166
-
167
- let overwrite_dtype_slice = overwrite_dtype_slice.map(|overwrite_dtype| {
168
- overwrite_dtype
169
- .iter()
170
- .map(|dt| dt.0.clone())
171
- .collect::<Vec<_>>()
172
- });
173
-
174
- let mmap_bytes_r = get_mmap_bytes_reader(rb_f)?;
175
- let df = CsvReader::new(mmap_bytes_r)
176
- .infer_schema(infer_schema_length)
177
- .has_header(has_header)
178
- .with_n_rows(n_rows)
179
- .with_separator(separator.as_bytes()[0])
180
- .with_skip_rows(skip_rows)
181
- .with_ignore_errors(ignore_errors)
182
- .with_projection(projection)
183
- .with_rechunk(rechunk)
184
- .with_chunk_size(chunk_size)
185
- .with_encoding(encoding.0)
186
- .with_columns(columns)
187
- .with_n_threads(n_threads)
188
- .with_path(path)
189
- .with_dtypes(overwrite_dtype.map(Arc::new))
190
- .with_dtypes_slice(overwrite_dtype_slice.as_deref())
191
- .low_memory(low_memory)
192
- .with_comment_prefix(comment_prefix.as_deref())
193
- .with_null_values(null_values)
194
- .with_try_parse_dates(try_parse_dates)
195
- .with_quote_char(quote_char)
196
- .with_end_of_line_char(eol_char)
197
- .with_skip_rows_after_header(skip_rows_after_header)
198
- .with_row_index(row_index)
199
- .sample_size(sample_size)
200
- .truncate_ragged_lines(truncate_ragged_lines)
201
- .finish()
202
- .map_err(RbPolarsErr::from)?;
203
- Ok(df.into())
204
- }
205
-
206
- #[allow(clippy::too_many_arguments)]
207
- pub fn read_parquet(
208
- rb_f: Value,
209
- columns: Option<Vec<String>>,
210
- projection: Option<Vec<usize>>,
211
- n_rows: Option<usize>,
212
- parallel: Wrap<ParallelStrategy>,
213
- row_index: Option<(String, IdxSize)>,
214
- low_memory: bool,
215
- use_statistics: bool,
216
- rechunk: bool,
217
- ) -> RbResult<Self> {
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)?;
246
- Ok(RbDataFrame::new(df))
247
- }
248
-
249
- pub fn read_ipc(
250
- rb_f: Value,
251
- columns: Option<Vec<String>>,
252
- projection: Option<Vec<usize>>,
253
- n_rows: Option<usize>,
254
- row_index: Option<(String, IdxSize)>,
255
- memory_map: bool,
256
- ) -> RbResult<Self> {
257
- let row_index = row_index.map(|(name, offset)| RowIndex { name, offset });
258
- let mmap_bytes_r = get_mmap_bytes_reader(rb_f)?;
259
- let df = IpcReader::new(mmap_bytes_r)
260
- .with_projection(projection)
261
- .with_columns(columns)
262
- .with_n_rows(n_rows)
263
- .with_row_index(row_index)
264
- .memory_mapped(memory_map)
265
- .finish()
266
- .map_err(RbPolarsErr::from)?;
267
- Ok(RbDataFrame::new(df))
268
- }
269
-
270
- pub fn read_avro(
271
- rb_f: Value,
272
- columns: Option<Vec<String>>,
273
- projection: Option<Vec<usize>>,
274
- n_rows: Option<usize>,
275
- ) -> RbResult<Self> {
276
- use polars::io::avro::AvroReader;
277
-
278
- let file = get_file_like(rb_f, false)?;
279
- let df = AvroReader::new(file)
280
- .with_projection(projection)
281
- .with_columns(columns)
282
- .with_n_rows(n_rows)
283
- .finish()
284
- .map_err(RbPolarsErr::from)?;
285
- Ok(RbDataFrame::new(df))
286
- }
287
-
288
- pub fn write_avro(
289
- &self,
290
- rb_f: Value,
291
- compression: Wrap<Option<AvroCompression>>,
292
- ) -> RbResult<()> {
293
- use polars::io::avro::AvroWriter;
294
-
295
- if let Ok(s) = String::try_convert(rb_f) {
296
- let f = std::fs::File::create(s).unwrap();
297
- AvroWriter::new(f)
298
- .with_compression(compression.0)
299
- .finish(&mut self.df.borrow_mut())
300
- .map_err(RbPolarsErr::from)?;
301
- } else {
302
- let mut buf = get_file_like(rb_f, true)?;
303
- AvroWriter::new(&mut buf)
304
- .with_compression(compression.0)
305
- .finish(&mut self.df.borrow_mut())
306
- .map_err(RbPolarsErr::from)?;
307
- }
308
-
309
- Ok(())
310
- }
311
-
312
- pub fn read_json(rb_f: Value) -> RbResult<Self> {
313
- // memmap the file first
314
- let mmap_bytes_r = get_mmap_bytes_reader(rb_f)?;
315
- let mmap_read: ReaderBytes = (&mmap_bytes_r).into();
316
- let bytes = mmap_read.deref();
317
-
318
- // Happy path is our column oriented json as that is most performant
319
- // on failure we try
320
- match serde_json::from_slice::<DataFrame>(bytes) {
321
- Ok(df) => Ok(df.into()),
322
- // try arrow json reader instead
323
- // this is row oriented
324
- Err(e) => {
325
- let msg = format!("{e}");
326
- if msg.contains("successful parse invalid data") {
327
- let e = RbPolarsErr::from(PolarsError::ComputeError(msg.into()));
328
- Err(e)
329
- } else {
330
- let out = JsonReader::new(mmap_bytes_r)
331
- .with_json_format(JsonFormat::Json)
332
- .finish()
333
- .map_err(|e| RbPolarsErr::other(format!("{:?}", e)))?;
334
- Ok(out.into())
335
- }
336
- }
337
- }
338
- }
339
-
340
- pub fn read_ndjson(rb_f: Value) -> RbResult<Self> {
341
- let mmap_bytes_r = get_mmap_bytes_reader(rb_f)?;
342
-
343
- let out = JsonReader::new(mmap_bytes_r)
344
- .with_json_format(JsonFormat::JsonLines)
345
- .finish()
346
- .map_err(|e| RbPolarsErr::other(format!("{:?}", e)))?;
347
- Ok(out.into())
348
- }
349
-
350
- pub fn write_json(&self, rb_f: Value, pretty: bool, row_oriented: bool) -> RbResult<()> {
351
- let file = BufWriter::new(get_file_like(rb_f, true)?);
352
-
353
- let r = match (pretty, row_oriented) {
354
- (_, true) => JsonWriter::new(file)
355
- .with_json_format(JsonFormat::Json)
356
- .finish(&mut self.df.borrow_mut()),
357
- (true, _) => serde_json::to_writer_pretty(file, &*self.df.borrow())
358
- .map_err(|e| PolarsError::ComputeError(format!("{:?}", e).into())),
359
- (false, _) => serde_json::to_writer(file, &*self.df.borrow())
360
- .map_err(|e| PolarsError::ComputeError(format!("{:?}", e).into())),
361
- };
362
- r.map_err(|e| RbPolarsErr::other(format!("{:?}", e)))?;
363
- Ok(())
364
- }
365
-
366
- pub fn write_ndjson(&self, rb_f: Value) -> RbResult<()> {
367
- let file = BufWriter::new(get_file_like(rb_f, true)?);
368
-
369
- let r = JsonWriter::new(file)
370
- .with_json_format(JsonFormat::JsonLines)
371
- .finish(&mut self.df.borrow_mut());
372
-
373
- r.map_err(|e| RbPolarsErr::other(format!("{:?}", e)))?;
374
- Ok(())
375
- }
376
-
377
- pub fn read_rows(
378
- rb_rows: RArray,
379
- infer_schema_length: Option<usize>,
380
- schema: Option<Wrap<Schema>>,
381
- ) -> RbResult<Self> {
382
- let mut rows = Vec::with_capacity(rb_rows.len());
383
- for v in rb_rows.each() {
384
- let rb_row = RArray::try_convert(v?)?;
385
- let mut row = Vec::with_capacity(rb_row.len());
386
- for val in rb_row.each() {
387
- row.push(Wrap::<AnyValue>::try_convert(val?)?.0);
388
- }
389
- rows.push(Row(row));
390
- }
391
- Self::finish_from_rows(rows, infer_schema_length, schema.map(|wrap| wrap.0), None)
392
- }
393
-
394
- pub fn read_hashes(
395
- dicts: Value,
396
- infer_schema_length: Option<usize>,
397
- schema: Option<Wrap<Schema>>,
398
- schema_overrides: Option<Wrap<Schema>>,
399
- ) -> RbResult<Self> {
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)?;
405
-
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
- }
412
- }
413
- }
414
- let rbdf = Self::finish_from_rows(
415
- rows,
416
- infer_schema_length,
417
- schema.map(|wrap| wrap.0),
418
- Some(schema_overrides_by_idx),
419
- )?;
420
-
421
- unsafe {
422
- rbdf.df
423
- .borrow_mut()
424
- .get_columns_mut()
425
- .iter_mut()
426
- .zip(&names)
427
- .for_each(|(s, name)| {
428
- s.rename(name);
429
- });
430
- }
431
- let length = names.len();
432
- if names.into_iter().collect::<PlHashSet<_>>().len() != length {
433
- let err = PolarsError::SchemaMismatch("duplicate column names found".into());
434
- Err(RbPolarsErr::from(err))?;
435
- }
436
-
437
- Ok(rbdf)
438
- }
439
-
440
- pub fn read_hash(data: RHash) -> RbResult<Self> {
441
- let mut cols: Vec<Series> = Vec::new();
442
- data.foreach(|name: String, values: Value| {
443
- let obj: Value = rb_modules::series().funcall("new", (name, values))?;
444
- let rbseries = obj.funcall::<_, _, &RbSeries>("_s", ())?;
445
- cols.push(rbseries.series.borrow().clone());
446
- Ok(ForEach::Continue)
447
- })?;
448
- let df = DataFrame::new(cols).map_err(RbPolarsErr::from)?;
449
- Ok(df.into())
450
- }
451
-
452
- #[allow(clippy::too_many_arguments)]
453
- pub fn write_csv(
454
- &self,
455
- rb_f: Value,
456
- include_header: bool,
457
- separator: u8,
458
- quote_char: u8,
459
- batch_size: Wrap<NonZeroUsize>,
460
- datetime_format: Option<String>,
461
- date_format: Option<String>,
462
- time_format: Option<String>,
463
- float_precision: Option<usize>,
464
- null_value: Option<String>,
465
- ) -> RbResult<()> {
466
- let batch_size = batch_size.0;
467
- let null = null_value.unwrap_or_default();
468
-
469
- if let Ok(s) = String::try_convert(rb_f) {
470
- let f = std::fs::File::create(s).unwrap();
471
- // no need for a buffered writer, because the csv writer does internal buffering
472
- CsvWriter::new(f)
473
- .include_header(include_header)
474
- .with_separator(separator)
475
- .with_quote_char(quote_char)
476
- .with_batch_size(batch_size)
477
- .with_datetime_format(datetime_format)
478
- .with_date_format(date_format)
479
- .with_time_format(time_format)
480
- .with_float_precision(float_precision)
481
- .with_null_value(null)
482
- .finish(&mut self.df.borrow_mut())
483
- .map_err(RbPolarsErr::from)?;
484
- } else {
485
- let mut buf = Cursor::new(Vec::new());
486
- CsvWriter::new(&mut buf)
487
- .include_header(include_header)
488
- .with_separator(separator)
489
- .with_quote_char(quote_char)
490
- .with_batch_size(batch_size)
491
- .with_datetime_format(datetime_format)
492
- .with_date_format(date_format)
493
- .with_time_format(time_format)
494
- .with_float_precision(float_precision)
495
- .with_null_value(null)
496
- .finish(&mut self.df.borrow_mut())
497
- .map_err(RbPolarsErr::from)?;
498
- // TODO less copying
499
- let rb_str = RString::from_slice(&buf.into_inner());
500
- rb_f.funcall::<_, _, Value>("write", (rb_str,))?;
501
- }
502
-
503
- Ok(())
504
- }
505
-
506
- pub fn write_ipc(
507
- &self,
508
- rb_f: Value,
509
- compression: Wrap<Option<IpcCompression>>,
510
- ) -> RbResult<()> {
511
- if let Ok(s) = String::try_convert(rb_f) {
512
- let f = std::fs::File::create(s).unwrap();
513
- IpcWriter::new(f)
514
- .with_compression(compression.0)
515
- .finish(&mut self.df.borrow_mut())
516
- .map_err(RbPolarsErr::from)?;
517
- } else {
518
- let mut buf = Cursor::new(Vec::new());
519
- IpcWriter::new(&mut buf)
520
- .with_compression(compression.0)
521
- .finish(&mut self.df.borrow_mut())
522
- .map_err(RbPolarsErr::from)?;
523
- // TODO less copying
524
- let rb_str = RString::from_slice(&buf.into_inner());
525
- rb_f.funcall::<_, _, Value>("write", (rb_str,))?;
526
- }
527
- Ok(())
528
- }
529
-
530
- pub fn row_tuple(&self, idx: i64) -> Value {
531
- let idx = if idx < 0 {
532
- (self.df.borrow().height() as i64 + idx) as usize
533
- } else {
534
- idx as usize
535
- };
536
- RArray::from_iter(
537
- self.df
538
- .borrow()
539
- .get_columns()
540
- .iter()
541
- .map(|s| match s.dtype() {
542
- DataType::Object(_, _) => {
543
- let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into());
544
- obj.unwrap().to_object()
545
- }
546
- _ => Wrap(s.get(idx).unwrap()).into_value(),
547
- }),
548
- )
549
- .as_value()
550
- }
551
-
552
- pub fn row_tuples(&self) -> Value {
553
- let df = &self.df;
554
- RArray::from_iter((0..df.borrow().height()).map(|idx| {
555
- RArray::from_iter(
556
- self.df
557
- .borrow()
558
- .get_columns()
559
- .iter()
560
- .map(|s| match s.dtype() {
561
- DataType::Object(_, _) => {
562
- let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into());
563
- obj.unwrap().to_object()
564
- }
565
- _ => Wrap(s.get(idx).unwrap()).into_value(),
566
- }),
567
- )
568
- }))
569
- .as_value()
570
- }
571
-
572
- pub fn to_numo(&self) -> Option<Value> {
573
- let mut st = None;
574
- for s in self.df.borrow().iter() {
575
- let dt_i = s.dtype();
576
- match st {
577
- None => st = Some(dt_i.clone()),
578
- Some(ref mut st) => {
579
- *st = try_get_supertype(st, dt_i).ok()?;
580
- }
581
- }
582
- }
583
- let _st = st?;
584
-
585
- // TODO
586
- None
587
- }
588
-
589
- pub fn write_parquet(
590
- &self,
591
- rb_f: Value,
592
- compression: String,
593
- compression_level: Option<i32>,
594
- statistics: bool,
595
- row_group_size: Option<usize>,
596
- data_page_size: Option<usize>,
597
- ) -> RbResult<()> {
598
- let compression = parse_parquet_compression(&compression, compression_level)?;
599
-
600
- if let Ok(s) = String::try_convert(rb_f) {
601
- let f = std::fs::File::create(s).unwrap();
602
- ParquetWriter::new(f)
603
- .with_compression(compression)
604
- .with_statistics(statistics)
605
- .with_row_group_size(row_group_size)
606
- .with_data_page_size(data_page_size)
607
- .finish(&mut self.df.borrow_mut())
608
- .map_err(RbPolarsErr::from)?;
609
- } else {
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)?;
618
- }
619
-
620
- Ok(())
621
- }
622
-
623
- pub fn add(&self, s: &RbSeries) -> RbResult<Self> {
624
- let df = (&*self.df.borrow() + &*s.series.borrow()).map_err(RbPolarsErr::from)?;
625
- Ok(df.into())
626
- }
627
-
628
- pub fn sub(&self, s: &RbSeries) -> RbResult<Self> {
629
- let df = (&*self.df.borrow() - &*s.series.borrow()).map_err(RbPolarsErr::from)?;
630
- Ok(df.into())
631
- }
632
-
633
- pub fn div(&self, s: &RbSeries) -> RbResult<Self> {
634
- let df = (&*self.df.borrow() / &*s.series.borrow()).map_err(RbPolarsErr::from)?;
635
- Ok(df.into())
636
- }
637
-
638
- pub fn mul(&self, s: &RbSeries) -> RbResult<Self> {
639
- let df = (&*self.df.borrow() * &*s.series.borrow()).map_err(RbPolarsErr::from)?;
640
- Ok(df.into())
641
- }
642
-
643
- pub fn rem(&self, s: &RbSeries) -> RbResult<Self> {
644
- let df = (&*self.df.borrow() % &*s.series.borrow()).map_err(RbPolarsErr::from)?;
645
- Ok(df.into())
646
- }
647
-
648
- pub fn add_df(&self, s: &Self) -> RbResult<Self> {
649
- let df = (&*self.df.borrow() + &*s.df.borrow()).map_err(RbPolarsErr::from)?;
650
- Ok(df.into())
651
- }
652
-
653
- pub fn sub_df(&self, s: &Self) -> RbResult<Self> {
654
- let df = (&*self.df.borrow() - &*s.df.borrow()).map_err(RbPolarsErr::from)?;
655
- Ok(df.into())
656
- }
657
-
658
- pub fn div_df(&self, s: &Self) -> RbResult<Self> {
659
- let df = (&*self.df.borrow() / &*s.df.borrow()).map_err(RbPolarsErr::from)?;
660
- Ok(df.into())
661
- }
662
-
663
- pub fn mul_df(&self, s: &Self) -> RbResult<Self> {
664
- let df = (&*self.df.borrow() * &*s.df.borrow()).map_err(RbPolarsErr::from)?;
665
- Ok(df.into())
666
- }
667
-
668
- pub fn rem_df(&self, s: &Self) -> RbResult<Self> {
669
- let df = (&*self.df.borrow() % &*s.df.borrow()).map_err(RbPolarsErr::from)?;
670
- Ok(df.into())
671
- }
672
-
673
- pub fn sample_n(
674
- &self,
675
- n: &RbSeries,
676
- with_replacement: bool,
677
- shuffle: bool,
678
- seed: Option<u64>,
679
- ) -> RbResult<Self> {
680
- let df = self
681
- .df
682
- .borrow()
683
- .sample_n(&n.series.borrow(), with_replacement, shuffle, seed)
684
- .map_err(RbPolarsErr::from)?;
685
- Ok(df.into())
686
- }
687
-
688
- pub fn sample_frac(
689
- &self,
690
- frac: &RbSeries,
691
- with_replacement: bool,
692
- shuffle: bool,
693
- seed: Option<u64>,
694
- ) -> RbResult<Self> {
695
- let df = self
696
- .df
697
- .borrow()
698
- .sample_frac(&frac.series.borrow(), with_replacement, shuffle, seed)
699
- .map_err(RbPolarsErr::from)?;
700
- Ok(df.into())
701
- }
702
-
703
- pub fn rechunk(&self) -> Self {
704
- self.df.borrow().agg_chunks().into()
705
- }
706
-
707
- pub fn to_s(&self) -> String {
708
- format!("{}", self.df.borrow())
709
- }
710
-
711
- pub fn get_columns(&self) -> RArray {
712
- let cols = self.df.borrow().get_columns().to_vec();
713
- to_rbseries_collection(cols)
714
- }
715
-
716
- pub fn columns(&self) -> Vec<String> {
717
- self.df
718
- .borrow()
719
- .get_column_names()
720
- .iter()
721
- .map(|v| v.to_string())
722
- .collect()
723
- }
724
-
725
- pub fn set_column_names(&self, names: Vec<String>) -> RbResult<()> {
726
- self.df
727
- .borrow_mut()
728
- .set_column_names(&names)
729
- .map_err(RbPolarsErr::from)?;
730
- Ok(())
731
- }
732
-
733
- pub fn dtypes(&self) -> RArray {
734
- RArray::from_iter(
735
- self.df
736
- .borrow()
737
- .iter()
738
- .map(|s| Wrap(s.dtype().clone()).into_value()),
739
- )
740
- }
741
-
742
- pub fn n_chunks(&self) -> usize {
743
- self.df.borrow().n_chunks()
744
- }
745
-
746
- pub fn shape(&self) -> (usize, usize) {
747
- self.df.borrow().shape()
748
- }
749
-
750
- pub fn height(&self) -> usize {
751
- self.df.borrow().height()
752
- }
753
-
754
- pub fn width(&self) -> usize {
755
- self.df.borrow().width()
756
- }
757
-
758
- pub fn hstack_mut(&self, columns: RArray) -> RbResult<()> {
759
- let columns = to_series_collection(columns)?;
760
- self.df
761
- .borrow_mut()
762
- .hstack_mut(&columns)
763
- .map_err(RbPolarsErr::from)?;
764
- Ok(())
765
- }
766
-
767
- pub fn hstack(&self, columns: RArray) -> RbResult<Self> {
768
- let columns = to_series_collection(columns)?;
769
- let df = self
770
- .df
771
- .borrow()
772
- .hstack(&columns)
773
- .map_err(RbPolarsErr::from)?;
774
- Ok(df.into())
775
- }
776
-
777
- pub fn extend(&self, df: &RbDataFrame) -> RbResult<()> {
778
- self.df
779
- .borrow_mut()
780
- .extend(&df.df.borrow())
781
- .map_err(RbPolarsErr::from)?;
782
- Ok(())
783
- }
784
-
785
- pub fn vstack_mut(&self, df: &RbDataFrame) -> RbResult<()> {
786
- self.df
787
- .borrow_mut()
788
- .vstack_mut(&df.df.borrow())
789
- .map_err(RbPolarsErr::from)?;
790
- Ok(())
791
- }
792
-
793
- pub fn vstack(&self, df: &RbDataFrame) -> RbResult<Self> {
794
- let df = self
795
- .df
796
- .borrow()
797
- .vstack(&df.df.borrow())
798
- .map_err(RbPolarsErr::from)?;
799
- Ok(df.into())
800
- }
801
-
802
- pub fn drop_in_place(&self, name: String) -> RbResult<RbSeries> {
803
- let s = self
804
- .df
805
- .borrow_mut()
806
- .drop_in_place(&name)
807
- .map_err(RbPolarsErr::from)?;
808
- Ok(RbSeries::new(s))
809
- }
810
-
811
- pub fn drop_nulls(&self, subset: Option<Vec<String>>) -> RbResult<Self> {
812
- let df = self
813
- .df
814
- .borrow()
815
- .drop_nulls(subset.as_ref().map(|s| s.as_ref()))
816
- .map_err(RbPolarsErr::from)?;
817
- Ok(df.into())
818
- }
819
-
820
- pub fn drop(&self, name: String) -> RbResult<Self> {
821
- let df = self.df.borrow().drop(&name).map_err(RbPolarsErr::from)?;
822
- Ok(RbDataFrame::new(df))
823
- }
824
-
825
- pub fn select_at_idx(&self, idx: usize) -> Option<RbSeries> {
826
- self.df
827
- .borrow()
828
- .select_at_idx(idx)
829
- .map(|s| RbSeries::new(s.clone()))
830
- }
831
-
832
- pub fn get_column_index(&self, name: String) -> Option<usize> {
833
- self.df.borrow().get_column_index(&name)
834
- }
835
-
836
- pub fn get_column(&self, name: String) -> RbResult<RbSeries> {
837
- self.df
838
- .borrow()
839
- .column(&name)
840
- .map(|s| RbSeries::new(s.clone()))
841
- .map_err(RbPolarsErr::from)
842
- }
843
-
844
- pub fn select(&self, selection: Vec<String>) -> RbResult<Self> {
845
- let df = self
846
- .df
847
- .borrow()
848
- .select(selection)
849
- .map_err(RbPolarsErr::from)?;
850
- Ok(RbDataFrame::new(df))
851
- }
852
-
853
- pub fn take(&self, indices: Vec<IdxSize>) -> RbResult<Self> {
854
- let indices = IdxCa::from_vec("", indices);
855
- let df = self.df.borrow().take(&indices).map_err(RbPolarsErr::from)?;
856
- Ok(RbDataFrame::new(df))
857
- }
858
-
859
- pub fn take_with_series(&self, indices: &RbSeries) -> RbResult<Self> {
860
- let binding = indices.series.borrow();
861
- let idx = binding.idx().map_err(RbPolarsErr::from)?;
862
- let df = self.df.borrow().take(idx).map_err(RbPolarsErr::from)?;
863
- Ok(RbDataFrame::new(df))
864
- }
865
-
866
- pub fn replace(&self, column: String, new_col: &RbSeries) -> RbResult<()> {
867
- self.df
868
- .borrow_mut()
869
- .replace(&column, new_col.series.borrow().clone())
870
- .map_err(RbPolarsErr::from)?;
871
- Ok(())
872
- }
873
-
874
- pub fn replace_column(&self, index: usize, new_col: &RbSeries) -> RbResult<()> {
875
- self.df
876
- .borrow_mut()
877
- .replace_column(index, new_col.series.borrow().clone())
878
- .map_err(RbPolarsErr::from)?;
879
- Ok(())
880
- }
881
-
882
- pub fn insert_column(&self, index: usize, new_col: &RbSeries) -> RbResult<()> {
883
- self.df
884
- .borrow_mut()
885
- .insert_column(index, new_col.series.borrow().clone())
886
- .map_err(RbPolarsErr::from)?;
887
- Ok(())
888
- }
889
-
890
- pub fn slice(&self, offset: usize, length: Option<usize>) -> Self {
891
- let df = self.df.borrow().slice(
892
- offset as i64,
893
- length.unwrap_or_else(|| self.df.borrow().height()),
894
- );
895
- df.into()
896
- }
897
-
898
- pub fn head(&self, length: Option<usize>) -> Self {
899
- self.df.borrow().head(length).into()
900
- }
901
-
902
- pub fn tail(&self, length: Option<usize>) -> Self {
903
- self.df.borrow().tail(length).into()
904
- }
905
-
906
- pub fn is_unique(&self) -> RbResult<RbSeries> {
907
- let mask = self.df.borrow().is_unique().map_err(RbPolarsErr::from)?;
908
- Ok(mask.into_series().into())
909
- }
910
-
911
- pub fn is_duplicated(&self) -> RbResult<RbSeries> {
912
- let mask = self
913
- .df
914
- .borrow()
915
- .is_duplicated()
916
- .map_err(RbPolarsErr::from)?;
917
- Ok(mask.into_series().into())
918
- }
919
-
920
- pub fn equals(&self, other: &RbDataFrame, null_equal: bool) -> bool {
921
- if null_equal {
922
- self.df.borrow().equals_missing(&other.df.borrow())
923
- } else {
924
- self.df.borrow().equals(&other.df.borrow())
925
- }
926
- }
927
-
928
- pub fn with_row_index(&self, name: String, offset: Option<IdxSize>) -> RbResult<Self> {
929
- let df = self
930
- .df
931
- .borrow()
932
- .with_row_index(&name, offset)
933
- .map_err(RbPolarsErr::from)?;
934
- Ok(df.into())
935
- }
936
-
937
- pub fn clone(&self) -> Self {
938
- RbDataFrame::new(self.df.borrow().clone())
939
- }
940
-
941
- pub fn melt(
942
- &self,
943
- id_vars: Vec<String>,
944
- value_vars: Vec<String>,
945
- value_name: Option<String>,
946
- variable_name: Option<String>,
947
- ) -> RbResult<Self> {
948
- let args = MeltArgs {
949
- id_vars: strings_to_smartstrings(id_vars),
950
- value_vars: strings_to_smartstrings(value_vars),
951
- value_name: value_name.map(|s| s.into()),
952
- variable_name: variable_name.map(|s| s.into()),
953
- streamable: false,
954
- };
955
-
956
- let df = self.df.borrow().melt2(args).map_err(RbPolarsErr::from)?;
957
- Ok(RbDataFrame::new(df))
958
- }
959
-
960
- #[allow(clippy::too_many_arguments)]
961
- pub fn pivot_expr(
962
- &self,
963
- index: Vec<String>,
964
- columns: Vec<String>,
965
- values: Option<Vec<String>>,
966
- maintain_order: bool,
967
- sort_columns: bool,
968
- aggregate_expr: Option<&RbExpr>,
969
- separator: Option<String>,
970
- ) -> RbResult<Self> {
971
- let fun = match maintain_order {
972
- true => pivot_stable,
973
- false => pivot,
974
- };
975
- let agg_expr = aggregate_expr.map(|aggregate_expr| aggregate_expr.inner.clone());
976
- let df = fun(
977
- &self.df.borrow(),
978
- index,
979
- columns,
980
- values,
981
- sort_columns,
982
- agg_expr,
983
- separator.as_deref(),
984
- )
985
- .map_err(RbPolarsErr::from)?;
986
- Ok(RbDataFrame::new(df))
987
- }
988
-
989
- pub fn partition_by(
990
- &self,
991
- by: Vec<String>,
992
- maintain_order: bool,
993
- include_key: bool,
994
- ) -> RbResult<RArray> {
995
- let out = if maintain_order {
996
- self.df.borrow().partition_by_stable(by, include_key)
997
- } else {
998
- self.df.borrow().partition_by(by, include_key)
999
- }
1000
- .map_err(RbPolarsErr::from)?;
1001
- Ok(RArray::from_iter(out.into_iter().map(RbDataFrame::new)))
1002
- }
1003
-
1004
- pub fn shift(&self, periods: i64) -> Self {
1005
- self.df.borrow().shift(periods).into()
1006
- }
1007
-
1008
- pub fn lazy(&self) -> RbLazyFrame {
1009
- self.df.borrow().clone().lazy().into()
1010
- }
1011
-
1012
- pub fn max_horizontal(&self) -> RbResult<Option<RbSeries>> {
1013
- let s = self
1014
- .df
1015
- .borrow()
1016
- .max_horizontal()
1017
- .map_err(RbPolarsErr::from)?;
1018
- Ok(s.map(|s| s.into()))
1019
- }
1020
-
1021
- pub fn min_horizontal(&self) -> RbResult<Option<RbSeries>> {
1022
- let s = self
1023
- .df
1024
- .borrow()
1025
- .min_horizontal()
1026
- .map_err(RbPolarsErr::from)?;
1027
- Ok(s.map(|s| s.into()))
1028
- }
1029
-
1030
- pub fn sum_horizontal(&self, ignore_nulls: bool) -> RbResult<Option<RbSeries>> {
1031
- let null_strategy = if ignore_nulls {
1032
- NullStrategy::Ignore
1033
- } else {
1034
- NullStrategy::Propagate
1035
- };
1036
- let s = self
1037
- .df
1038
- .borrow()
1039
- .sum_horizontal(null_strategy)
1040
- .map_err(RbPolarsErr::from)?;
1041
- Ok(s.map(|s| s.into()))
1042
- }
1043
-
1044
- pub fn mean_horizontal(&self, ignore_nulls: bool) -> RbResult<Option<RbSeries>> {
1045
- let null_strategy = if ignore_nulls {
1046
- NullStrategy::Ignore
1047
- } else {
1048
- NullStrategy::Propagate
1049
- };
1050
- let s = self
1051
- .df
1052
- .borrow()
1053
- .mean_horizontal(null_strategy)
1054
- .map_err(RbPolarsErr::from)?;
1055
- Ok(s.map(|s| s.into()))
1056
- }
1057
-
1058
- pub fn to_dummies(
1059
- &self,
1060
- columns: Option<Vec<String>>,
1061
- separator: Option<String>,
1062
- drop_first: bool,
1063
- ) -> RbResult<Self> {
1064
- let df = match columns {
1065
- Some(cols) => self.df.borrow().columns_to_dummies(
1066
- cols.iter().map(|x| x as &str).collect(),
1067
- separator.as_deref(),
1068
- drop_first,
1069
- ),
1070
- None => self
1071
- .df
1072
- .borrow()
1073
- .to_dummies(separator.as_deref(), drop_first),
1074
- }
1075
- .map_err(RbPolarsErr::from)?;
1076
- Ok(df.into())
1077
- }
1078
-
1079
- pub fn null_count(&self) -> Self {
1080
- let df = self.df.borrow().null_count();
1081
- df.into()
1082
- }
1083
-
1084
- pub fn apply(
1085
- &self,
1086
- lambda: Value,
1087
- output_type: Option<Wrap<DataType>>,
1088
- inference_size: usize,
1089
- ) -> RbResult<(Value, bool)> {
1090
- let df = &self.df.borrow();
1091
-
1092
- let output_type = output_type.map(|dt| dt.0);
1093
- let out = match output_type {
1094
- Some(DataType::Int32) => {
1095
- apply_lambda_with_primitive_out_type::<Int32Type>(df, lambda, 0, None).into_series()
1096
- }
1097
- Some(DataType::Int64) => {
1098
- apply_lambda_with_primitive_out_type::<Int64Type>(df, lambda, 0, None).into_series()
1099
- }
1100
- Some(DataType::UInt32) => {
1101
- apply_lambda_with_primitive_out_type::<UInt32Type>(df, lambda, 0, None)
1102
- .into_series()
1103
- }
1104
- Some(DataType::UInt64) => {
1105
- apply_lambda_with_primitive_out_type::<UInt64Type>(df, lambda, 0, None)
1106
- .into_series()
1107
- }
1108
- Some(DataType::Float32) => {
1109
- apply_lambda_with_primitive_out_type::<Float32Type>(df, lambda, 0, None)
1110
- .into_series()
1111
- }
1112
- Some(DataType::Float64) => {
1113
- apply_lambda_with_primitive_out_type::<Float64Type>(df, lambda, 0, None)
1114
- .into_series()
1115
- }
1116
- Some(DataType::Boolean) => {
1117
- apply_lambda_with_bool_out_type(df, lambda, 0, None).into_series()
1118
- }
1119
- Some(DataType::Date) => {
1120
- apply_lambda_with_primitive_out_type::<Int32Type>(df, lambda, 0, None)
1121
- .into_date()
1122
- .into_series()
1123
- }
1124
- Some(DataType::Datetime(tu, tz)) => {
1125
- apply_lambda_with_primitive_out_type::<Int64Type>(df, lambda, 0, None)
1126
- .into_datetime(tu, tz)
1127
- .into_series()
1128
- }
1129
- Some(DataType::String) => {
1130
- apply_lambda_with_utf8_out_type(df, lambda, 0, None).into_series()
1131
- }
1132
- _ => return apply_lambda_unknown(df, lambda, inference_size),
1133
- };
1134
-
1135
- Ok((Obj::wrap(RbSeries::from(out)).as_value(), false))
1136
- }
1137
-
1138
- pub fn shrink_to_fit(&self) {
1139
- self.df.borrow_mut().shrink_to_fit();
1140
- }
1141
-
1142
- pub fn hash_rows(&self, k0: u64, k1: u64, k2: u64, k3: u64) -> RbResult<RbSeries> {
1143
- let hb = ahash::RandomState::with_seeds(k0, k1, k2, k3);
1144
- let hash = self
1145
- .df
1146
- .borrow_mut()
1147
- .hash_rows(Some(hb))
1148
- .map_err(RbPolarsErr::from)?;
1149
- Ok(hash.into_series().into())
1150
- }
1151
-
1152
- pub fn transpose(&self, keep_names_as: Option<String>, column_names: Value) -> RbResult<Self> {
1153
- let new_col_names = if let Ok(name) = <Vec<String>>::try_convert(column_names) {
1154
- Some(Either::Right(name))
1155
- } else if let Ok(name) = String::try_convert(column_names) {
1156
- Some(Either::Left(name))
1157
- } else {
1158
- None
1159
- };
1160
- Ok(self
1161
- .df
1162
- .borrow_mut()
1163
- .transpose(keep_names_as.as_deref(), new_col_names)
1164
- .map_err(RbPolarsErr::from)?
1165
- .into())
1166
- }
1167
-
1168
- pub fn upsample(
1169
- &self,
1170
- by: Vec<String>,
1171
- index_column: String,
1172
- every: String,
1173
- offset: String,
1174
- stable: bool,
1175
- ) -> RbResult<Self> {
1176
- let out = if stable {
1177
- self.df.borrow().upsample_stable(
1178
- by,
1179
- &index_column,
1180
- Duration::parse(&every),
1181
- Duration::parse(&offset),
1182
- )
1183
- } else {
1184
- self.df.borrow().upsample(
1185
- by,
1186
- &index_column,
1187
- Duration::parse(&every),
1188
- Duration::parse(&offset),
1189
- )
1190
- };
1191
- let out = out.map_err(RbPolarsErr::from)?;
1192
- Ok(out.into())
1193
- }
1194
-
1195
- pub fn to_struct(&self, name: String) -> RbSeries {
1196
- let s = self.df.borrow().clone().into_struct(&name);
1197
- s.into_series().into()
1198
- }
1199
-
1200
- pub fn unnest(&self, names: Vec<String>) -> RbResult<Self> {
1201
- let df = self.df.borrow().unnest(names).map_err(RbPolarsErr::from)?;
1202
- Ok(df.into())
1203
- }
1204
-
1205
- pub fn clear(&self) -> Self {
1206
- self.df.borrow().clear().into()
1207
- }
1208
- }