polars-df 0.9.0 → 0.11.0

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