polars-df 0.8.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/file.rs
CHANGED
@@ -1,20 +1,167 @@
|
|
1
|
-
use magnus::{exception, prelude::*, Error, RString, Value};
|
2
|
-
use polars::io::mmap::MmapBytesReader;
|
3
1
|
use std::fs::File;
|
4
|
-
use std::io
|
2
|
+
use std::io;
|
3
|
+
use std::io::{BufReader, Cursor, Read, Seek, SeekFrom, Write};
|
5
4
|
use std::path::PathBuf;
|
6
5
|
|
6
|
+
use magnus::{exception, prelude::*, Error, RString, Value};
|
7
|
+
use polars::io::mmap::MmapBytesReader;
|
8
|
+
|
9
|
+
use crate::error::RbPolarsErr;
|
10
|
+
use crate::prelude::resolve_homedir;
|
7
11
|
use crate::RbResult;
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
#[derive(Clone)]
|
14
|
+
pub struct RbFileLikeObject {
|
15
|
+
inner: Value,
|
16
|
+
}
|
17
|
+
|
18
|
+
/// Wraps a `Value`, and implements read, seek, and write for it.
|
19
|
+
impl RbFileLikeObject {
|
20
|
+
/// Creates an instance of a `RbFileLikeObject` from a `Value`.
|
21
|
+
/// To assert the object has the required methods methods,
|
22
|
+
/// instantiate it with `RbFileLikeObject::require`
|
23
|
+
pub fn new(object: Value) -> Self {
|
24
|
+
RbFileLikeObject { inner: object }
|
25
|
+
}
|
26
|
+
|
27
|
+
pub fn as_buffer(&self) -> std::io::Cursor<Vec<u8>> {
|
28
|
+
let data = self.as_file_buffer().into_inner();
|
29
|
+
std::io::Cursor::new(data)
|
30
|
+
}
|
31
|
+
|
32
|
+
pub fn as_file_buffer(&self) -> Cursor<Vec<u8>> {
|
33
|
+
let bytes = self
|
34
|
+
.inner
|
35
|
+
.funcall::<_, _, RString>("read", ())
|
36
|
+
.expect("no read method found");
|
37
|
+
|
38
|
+
let buf = unsafe { bytes.as_slice() }.to_vec();
|
39
|
+
|
40
|
+
Cursor::new(buf)
|
41
|
+
}
|
42
|
+
|
43
|
+
/// Same as `RbFileLikeObject::new`, but validates that the underlying
|
44
|
+
/// ruby object has a `read`, `write`, and `seek` methods in respect to parameters.
|
45
|
+
/// Will return a `TypeError` if object does not have `read`, `seek`, and `write` methods.
|
46
|
+
pub fn with_requirements(object: Value, read: bool, write: bool, seek: bool) -> RbResult<Self> {
|
47
|
+
if read && !object.respond_to("read", false)? {
|
48
|
+
return Err(Error::new(
|
49
|
+
exception::type_error(),
|
50
|
+
"Object does not have a .read() method.",
|
51
|
+
));
|
52
|
+
}
|
53
|
+
|
54
|
+
if seek && !object.respond_to("seek", false)? {
|
55
|
+
return Err(Error::new(
|
56
|
+
exception::type_error(),
|
57
|
+
"Object does not have a .seek() method.",
|
58
|
+
));
|
59
|
+
}
|
60
|
+
|
61
|
+
if write && !object.respond_to("write", false)? {
|
62
|
+
return Err(Error::new(
|
63
|
+
exception::type_error(),
|
64
|
+
"Object does not have a .write() method.",
|
65
|
+
));
|
66
|
+
}
|
67
|
+
|
68
|
+
Ok(RbFileLikeObject::new(object))
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
/// Extracts a string repr from, and returns an IO error to send back to rust.
|
73
|
+
fn rberr_to_io_err(e: Error) -> io::Error {
|
74
|
+
io::Error::new(io::ErrorKind::Other, e.to_string())
|
75
|
+
}
|
76
|
+
|
77
|
+
impl Read for RbFileLikeObject {
|
78
|
+
fn read(&mut self, mut buf: &mut [u8]) -> Result<usize, io::Error> {
|
79
|
+
let bytes = self
|
80
|
+
.inner
|
81
|
+
.funcall::<_, _, RString>("read", (buf.len(),))
|
82
|
+
.map_err(rberr_to_io_err)?;
|
83
|
+
|
84
|
+
buf.write_all(unsafe { bytes.as_slice() })?;
|
85
|
+
|
86
|
+
Ok(bytes.len())
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
impl Write for RbFileLikeObject {
|
91
|
+
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
|
92
|
+
let rbbytes = RString::from_slice(buf);
|
93
|
+
|
94
|
+
let number_bytes_written = self
|
95
|
+
.inner
|
96
|
+
.funcall::<_, _, usize>("write", (rbbytes,))
|
97
|
+
.map_err(rberr_to_io_err)?;
|
98
|
+
|
99
|
+
Ok(number_bytes_written)
|
100
|
+
}
|
101
|
+
|
102
|
+
fn flush(&mut self) -> Result<(), io::Error> {
|
103
|
+
self.inner
|
104
|
+
.funcall::<_, _, Value>("flush", ())
|
105
|
+
.map_err(rberr_to_io_err)?;
|
106
|
+
|
107
|
+
Ok(())
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
impl Seek for RbFileLikeObject {
|
112
|
+
fn seek(&mut self, pos: SeekFrom) -> Result<u64, io::Error> {
|
113
|
+
let (whence, offset) = match pos {
|
114
|
+
SeekFrom::Start(i) => (0, i as i64),
|
115
|
+
SeekFrom::Current(i) => (1, i),
|
116
|
+
SeekFrom::End(i) => (2, i),
|
117
|
+
};
|
118
|
+
|
119
|
+
let new_position = self
|
120
|
+
.inner
|
121
|
+
.funcall("seek", (offset, whence))
|
122
|
+
.map_err(rberr_to_io_err)?;
|
123
|
+
|
124
|
+
Ok(new_position)
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
pub trait FileLike: Read + Write + Seek {}
|
129
|
+
|
130
|
+
impl FileLike for File {}
|
131
|
+
impl FileLike for RbFileLikeObject {}
|
132
|
+
|
133
|
+
pub enum EitherRustRubyFile {
|
134
|
+
Rb(RbFileLikeObject),
|
135
|
+
Rust(BufReader<File>),
|
136
|
+
}
|
137
|
+
|
138
|
+
///
|
139
|
+
/// # Arguments
|
140
|
+
/// * `truncate` - open or create a new file.
|
141
|
+
pub fn get_either_file(rb_f: Value, truncate: bool) -> RbResult<EitherRustRubyFile> {
|
142
|
+
if let Ok(rstring) = RString::try_convert(rb_f) {
|
143
|
+
let s = unsafe { rstring.as_str() }?;
|
144
|
+
let file_path = std::path::Path::new(&s);
|
145
|
+
let file_path = resolve_homedir(file_path);
|
146
|
+
let f = if truncate {
|
147
|
+
File::create(file_path).map_err(RbPolarsErr::io)?
|
148
|
+
} else {
|
149
|
+
polars_utils::open_file(&file_path).map_err(RbPolarsErr::from)?
|
150
|
+
};
|
151
|
+
let reader = BufReader::new(f);
|
152
|
+
Ok(EitherRustRubyFile::Rust(reader))
|
14
153
|
} else {
|
15
|
-
|
16
|
-
|
17
|
-
|
154
|
+
let f = RbFileLikeObject::with_requirements(rb_f, !truncate, truncate, !truncate)?;
|
155
|
+
Ok(EitherRustRubyFile::Rb(f))
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
pub fn get_file_like(f: Value, truncate: bool) -> RbResult<Box<dyn FileLike>> {
|
160
|
+
use EitherRustRubyFile::*;
|
161
|
+
match get_either_file(f, truncate)? {
|
162
|
+
Rb(f) => Ok(Box::new(f)),
|
163
|
+
Rust(f) => Ok(Box::new(f.into_inner())),
|
164
|
+
}
|
18
165
|
}
|
19
166
|
|
20
167
|
pub fn get_mmap_bytes_reader(rb_f: Value) -> RbResult<Box<dyn MmapBytesReader>> {
|
@@ -33,3 +33,9 @@ pub fn sum_horizontal(exprs: RArray) -> RbResult<RbExpr> {
|
|
33
33
|
let e = dsl::sum_horizontal(exprs).map_err(RbPolarsErr::from)?;
|
34
34
|
Ok(e.into())
|
35
35
|
}
|
36
|
+
|
37
|
+
pub fn mean_horizontal(exprs: RArray) -> RbResult<RbExpr> {
|
38
|
+
let exprs = rb_exprs_to_exprs(exprs)?;
|
39
|
+
let e = dsl::mean_horizontal(exprs).map_err(RbPolarsErr::from)?;
|
40
|
+
Ok(e.into())
|
41
|
+
}
|
@@ -17,9 +17,62 @@ macro_rules! set_unwrapped_or_0 {
|
|
17
17
|
};
|
18
18
|
}
|
19
19
|
|
20
|
-
pub fn
|
20
|
+
pub fn rolling_corr(
|
21
|
+
x: &RbExpr,
|
22
|
+
y: &RbExpr,
|
23
|
+
window_size: IdxSize,
|
24
|
+
min_periods: IdxSize,
|
25
|
+
ddof: u8,
|
26
|
+
) -> RbExpr {
|
27
|
+
dsl::rolling_corr(
|
28
|
+
x.inner.clone(),
|
29
|
+
y.inner.clone(),
|
30
|
+
RollingCovOptions {
|
31
|
+
min_periods,
|
32
|
+
window_size,
|
33
|
+
ddof,
|
34
|
+
},
|
35
|
+
)
|
36
|
+
.into()
|
37
|
+
}
|
38
|
+
|
39
|
+
pub fn rolling_cov(
|
40
|
+
x: &RbExpr,
|
41
|
+
y: &RbExpr,
|
42
|
+
window_size: IdxSize,
|
43
|
+
min_periods: IdxSize,
|
44
|
+
ddof: u8,
|
45
|
+
) -> RbExpr {
|
46
|
+
dsl::rolling_cov(
|
47
|
+
x.inner.clone(),
|
48
|
+
y.inner.clone(),
|
49
|
+
RollingCovOptions {
|
50
|
+
min_periods,
|
51
|
+
window_size,
|
52
|
+
ddof,
|
53
|
+
},
|
54
|
+
)
|
55
|
+
.into()
|
56
|
+
}
|
57
|
+
|
58
|
+
pub fn arg_sort_by(
|
59
|
+
by: RArray,
|
60
|
+
descending: Vec<bool>,
|
61
|
+
nulls_last: bool,
|
62
|
+
multithreaded: bool,
|
63
|
+
maintain_order: bool,
|
64
|
+
) -> RbResult<RbExpr> {
|
21
65
|
let by = rb_exprs_to_exprs(by)?;
|
22
|
-
Ok(dsl::arg_sort_by(
|
66
|
+
Ok(dsl::arg_sort_by(
|
67
|
+
by,
|
68
|
+
SortMultipleOptions {
|
69
|
+
descending,
|
70
|
+
nulls_last,
|
71
|
+
multithreaded,
|
72
|
+
maintain_order,
|
73
|
+
},
|
74
|
+
)
|
75
|
+
.into())
|
23
76
|
}
|
24
77
|
|
25
78
|
pub fn arg_where(condition: &RbExpr) -> RbExpr {
|
@@ -83,6 +136,47 @@ pub fn concat_lf(
|
|
83
136
|
Ok(lf.into())
|
84
137
|
}
|
85
138
|
|
139
|
+
pub fn concat_list(s: RArray) -> RbResult<RbExpr> {
|
140
|
+
let s = rb_exprs_to_exprs(s)?;
|
141
|
+
let expr = dsl::concat_list(s).map_err(RbPolarsErr::from)?;
|
142
|
+
Ok(expr.into())
|
143
|
+
}
|
144
|
+
|
145
|
+
pub fn concat_str(s: RArray, separator: String, ignore_nulls: bool) -> RbResult<RbExpr> {
|
146
|
+
let s = rb_exprs_to_exprs(s)?;
|
147
|
+
Ok(dsl::concat_str(s, &separator, ignore_nulls).into())
|
148
|
+
}
|
149
|
+
|
150
|
+
pub fn len() -> RbExpr {
|
151
|
+
dsl::len().into()
|
152
|
+
}
|
153
|
+
|
154
|
+
pub fn cov(a: &RbExpr, b: &RbExpr, ddof: u8) -> RbExpr {
|
155
|
+
polars::lazy::dsl::cov(a.inner.clone(), b.inner.clone(), ddof).into()
|
156
|
+
}
|
157
|
+
|
158
|
+
pub fn arctan2(y: &RbExpr, x: &RbExpr) -> RbExpr {
|
159
|
+
y.inner.clone().arctan2(x.inner.clone()).into()
|
160
|
+
}
|
161
|
+
|
162
|
+
pub fn arctan2d(y: &RbExpr, x: &RbExpr) -> RbExpr {
|
163
|
+
y.inner.clone().arctan2(x.inner.clone()).degrees().into()
|
164
|
+
}
|
165
|
+
|
166
|
+
pub fn cum_fold(
|
167
|
+
acc: &RbExpr,
|
168
|
+
lambda: Value,
|
169
|
+
exprs: RArray,
|
170
|
+
include_init: bool,
|
171
|
+
) -> RbResult<RbExpr> {
|
172
|
+
let exprs = rb_exprs_to_exprs(exprs)?;
|
173
|
+
let lambda = Opaque::from(lambda);
|
174
|
+
|
175
|
+
let func =
|
176
|
+
move |a: Series, b: Series| binary_lambda(Ruby::get().unwrap().get_inner(lambda), a, b);
|
177
|
+
Ok(dsl::cum_fold_exprs(acc.inner.clone(), func, exprs, include_init).into())
|
178
|
+
}
|
179
|
+
|
86
180
|
pub fn concat_lf_diagonal(
|
87
181
|
lfs: RArray,
|
88
182
|
rechunk: bool,
|
@@ -110,6 +204,19 @@ pub fn concat_lf_diagonal(
|
|
110
204
|
Ok(lf.into())
|
111
205
|
}
|
112
206
|
|
207
|
+
pub fn dtype_cols(dtypes: Vec<DataType>) -> RbExpr {
|
208
|
+
dsl::dtype_cols(dtypes).into()
|
209
|
+
}
|
210
|
+
|
211
|
+
pub fn dtype_cols2(dtypes: RArray) -> RbResult<RbExpr> {
|
212
|
+
let dtypes = dtypes
|
213
|
+
.each()
|
214
|
+
.map(|v| Wrap::<DataType>::try_convert(v?))
|
215
|
+
.collect::<RbResult<Vec<Wrap<DataType>>>>()?;
|
216
|
+
let dtypes = vec_extract_wrapped(dtypes);
|
217
|
+
Ok(crate::functions::lazy::dtype_cols(dtypes))
|
218
|
+
}
|
219
|
+
|
113
220
|
#[allow(clippy::too_many_arguments)]
|
114
221
|
pub fn duration(
|
115
222
|
weeks: Option<&RbExpr>,
|
@@ -146,38 +253,21 @@ pub fn duration(
|
|
146
253
|
dsl::duration(args).into()
|
147
254
|
}
|
148
255
|
|
149
|
-
pub fn count() -> RbExpr {
|
150
|
-
dsl::count().into()
|
151
|
-
}
|
152
|
-
|
153
256
|
pub fn first() -> RbExpr {
|
154
257
|
dsl::first().into()
|
155
258
|
}
|
156
259
|
|
157
|
-
pub fn last() -> RbExpr {
|
158
|
-
dsl::last().into()
|
159
|
-
}
|
160
|
-
|
161
|
-
pub fn dtype_cols(dtypes: Vec<DataType>) -> RbExpr {
|
162
|
-
dsl::dtype_cols(dtypes).into()
|
163
|
-
}
|
164
|
-
|
165
260
|
pub fn fold(acc: &RbExpr, lambda: Value, exprs: RArray) -> RbResult<RbExpr> {
|
166
261
|
let exprs = rb_exprs_to_exprs(exprs)?;
|
167
262
|
let lambda = Opaque::from(lambda);
|
168
263
|
|
169
264
|
let func =
|
170
265
|
move |a: Series, b: Series| binary_lambda(Ruby::get().unwrap().get_inner(lambda), a, b);
|
171
|
-
Ok(
|
266
|
+
Ok(dsl::fold_exprs(acc.inner.clone(), func, exprs).into())
|
172
267
|
}
|
173
268
|
|
174
|
-
pub fn
|
175
|
-
|
176
|
-
let lambda = Opaque::from(lambda);
|
177
|
-
|
178
|
-
let func =
|
179
|
-
move |a: Series, b: Series| binary_lambda(Ruby::get().unwrap().get_inner(lambda), a, b);
|
180
|
-
Ok(polars::lazy::dsl::cum_fold_exprs(acc.inner.clone(), func, exprs, include_init).into())
|
269
|
+
pub fn last() -> RbExpr {
|
270
|
+
dsl::last().into()
|
181
271
|
}
|
182
272
|
|
183
273
|
pub fn lit(value: Value, allow_object: bool) -> RbResult<RbExpr> {
|
@@ -219,6 +309,10 @@ pub fn lit(value: Value, allow_object: bool) -> RbResult<RbExpr> {
|
|
219
309
|
}
|
220
310
|
}
|
221
311
|
|
312
|
+
pub fn pearson_corr(a: &RbExpr, b: &RbExpr, ddof: u8) -> RbExpr {
|
313
|
+
dsl::pearson_corr(a.inner.clone(), b.inner.clone(), ddof).into()
|
314
|
+
}
|
315
|
+
|
222
316
|
pub fn repeat(value: &RbExpr, n: &RbExpr, dtype: Option<Wrap<DataType>>) -> RbResult<RbExpr> {
|
223
317
|
let mut value = value.inner.clone();
|
224
318
|
let n = n.inner.clone();
|
@@ -228,7 +322,7 @@ pub fn repeat(value: &RbExpr, n: &RbExpr, dtype: Option<Wrap<DataType>>) -> RbRe
|
|
228
322
|
}
|
229
323
|
|
230
324
|
if let Expr::Literal(lv) = &value {
|
231
|
-
let av = lv.
|
325
|
+
let av = lv.to_any_value().unwrap();
|
232
326
|
// Integer inputs that fit in Int32 are parsed as such
|
233
327
|
if let DataType::Int64 = av.dtype() {
|
234
328
|
let int_value = av.try_extract::<i64>().unwrap();
|
@@ -240,35 +334,11 @@ pub fn repeat(value: &RbExpr, n: &RbExpr, dtype: Option<Wrap<DataType>>) -> RbRe
|
|
240
334
|
Ok(dsl::repeat(value, n).into())
|
241
335
|
}
|
242
336
|
|
243
|
-
pub fn pearson_corr(a: &RbExpr, b: &RbExpr, ddof: u8) -> RbExpr {
|
244
|
-
polars::lazy::dsl::pearson_corr(a.inner.clone(), b.inner.clone(), ddof).into()
|
245
|
-
}
|
246
|
-
|
247
337
|
pub fn spearman_rank_corr(a: &RbExpr, b: &RbExpr, ddof: u8, propagate_nans: bool) -> RbExpr {
|
248
|
-
|
249
|
-
.into()
|
250
|
-
}
|
251
|
-
|
252
|
-
pub fn cov(a: &RbExpr, b: &RbExpr, ddof: u8) -> RbExpr {
|
253
|
-
polars::lazy::dsl::cov(a.inner.clone(), b.inner.clone(), ddof).into()
|
254
|
-
}
|
255
|
-
|
256
|
-
pub fn concat_str(s: RArray, sep: String) -> RbResult<RbExpr> {
|
257
|
-
let s = rb_exprs_to_exprs(s)?;
|
258
|
-
Ok(dsl::concat_str(s, &sep).into())
|
338
|
+
dsl::spearman_rank_corr(a.inner.clone(), b.inner.clone(), ddof, propagate_nans).into()
|
259
339
|
}
|
260
340
|
|
261
|
-
pub fn
|
262
|
-
let
|
263
|
-
let expr = dsl::concat_list(s).map_err(RbPolarsErr::from)?;
|
341
|
+
pub fn sql_expr(sql: String) -> RbResult<RbExpr> {
|
342
|
+
let expr = polars::sql::sql_expr(sql).map_err(RbPolarsErr::from)?;
|
264
343
|
Ok(expr.into())
|
265
344
|
}
|
266
|
-
|
267
|
-
pub fn dtype_cols2(dtypes: RArray) -> RbResult<RbExpr> {
|
268
|
-
let dtypes = dtypes
|
269
|
-
.each()
|
270
|
-
.map(|v| Wrap::<DataType>::try_convert(v?))
|
271
|
-
.collect::<RbResult<Vec<Wrap<DataType>>>>()?;
|
272
|
-
let dtypes = vec_extract_wrapped(dtypes);
|
273
|
-
Ok(crate::functions::lazy::dtype_cols(dtypes))
|
274
|
-
}
|
@@ -7,7 +7,7 @@ use polars_core::POOL;
|
|
7
7
|
use crate::conversion::Wrap;
|
8
8
|
use crate::{RbResult, RbValueError};
|
9
9
|
|
10
|
-
pub fn
|
10
|
+
pub fn get_index_type() -> Value {
|
11
11
|
Wrap(IDX_DTYPE).into_value()
|
12
12
|
}
|
13
13
|
|
@@ -36,3 +36,47 @@ pub fn get_float_fmt() -> RbResult<String> {
|
|
36
36
|
};
|
37
37
|
Ok(strfmt.to_string())
|
38
38
|
}
|
39
|
+
|
40
|
+
pub fn set_float_precision(precision: Option<usize>) -> RbResult<()> {
|
41
|
+
use polars_core::fmt::set_float_precision;
|
42
|
+
set_float_precision(precision);
|
43
|
+
Ok(())
|
44
|
+
}
|
45
|
+
|
46
|
+
pub fn get_float_precision() -> RbResult<Option<usize>> {
|
47
|
+
use polars_core::fmt::get_float_precision;
|
48
|
+
Ok(get_float_precision())
|
49
|
+
}
|
50
|
+
|
51
|
+
pub fn set_thousands_separator(sep: Option<char>) -> RbResult<()> {
|
52
|
+
use polars_core::fmt::set_thousands_separator;
|
53
|
+
set_thousands_separator(sep);
|
54
|
+
Ok(())
|
55
|
+
}
|
56
|
+
|
57
|
+
pub fn get_thousands_separator() -> RbResult<Option<String>> {
|
58
|
+
use polars_core::fmt::get_thousands_separator;
|
59
|
+
Ok(Some(get_thousands_separator()))
|
60
|
+
}
|
61
|
+
|
62
|
+
pub fn set_decimal_separator(sep: Option<char>) -> RbResult<()> {
|
63
|
+
use polars_core::fmt::set_decimal_separator;
|
64
|
+
set_decimal_separator(sep);
|
65
|
+
Ok(())
|
66
|
+
}
|
67
|
+
|
68
|
+
pub fn get_decimal_separator() -> RbResult<Option<char>> {
|
69
|
+
use polars_core::fmt::get_decimal_separator;
|
70
|
+
Ok(Some(get_decimal_separator()))
|
71
|
+
}
|
72
|
+
|
73
|
+
pub fn set_trim_decimal_zeros(trim: Option<bool>) -> RbResult<()> {
|
74
|
+
use polars_core::fmt::set_trim_decimal_zeros;
|
75
|
+
set_trim_decimal_zeros(trim);
|
76
|
+
Ok(())
|
77
|
+
}
|
78
|
+
|
79
|
+
pub fn get_trim_decimal_zeros() -> RbResult<Option<bool>> {
|
80
|
+
use polars_core::fmt::get_trim_decimal_zeros;
|
81
|
+
Ok(Some(get_trim_decimal_zeros()))
|
82
|
+
}
|
@@ -1,3 +1,7 @@
|
|
1
|
+
use crate::RbResult;
|
2
|
+
use magnus::{RArray, Ruby, Value};
|
3
|
+
use polars_core::StringCacheHolder;
|
4
|
+
|
1
5
|
pub fn enable_string_cache() {
|
2
6
|
polars_core::enable_string_cache()
|
3
7
|
}
|
@@ -9,3 +13,13 @@ pub fn disable_string_cache() {
|
|
9
13
|
pub fn using_string_cache() -> bool {
|
10
14
|
polars_core::using_string_cache()
|
11
15
|
}
|
16
|
+
|
17
|
+
#[magnus::wrap(class = "Polars::RbStringCacheHolder")]
|
18
|
+
pub struct RbStringCacheHolder {}
|
19
|
+
|
20
|
+
impl RbStringCacheHolder {
|
21
|
+
pub fn hold() -> RbResult<Value> {
|
22
|
+
let _hold = StringCacheHolder::hold();
|
23
|
+
Ruby::get().unwrap().yield_splat(RArray::new())
|
24
|
+
}
|
25
|
+
}
|
@@ -2,42 +2,72 @@ use polars::lazy::dsl;
|
|
2
2
|
|
3
3
|
use crate::RbExpr;
|
4
4
|
|
5
|
+
pub fn when(condition: &RbExpr) -> RbWhen {
|
6
|
+
RbWhen {
|
7
|
+
inner: dsl::when(condition.inner.clone()),
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
5
11
|
#[magnus::wrap(class = "Polars::RbWhen")]
|
6
12
|
#[derive(Clone)]
|
7
13
|
pub struct RbWhen {
|
8
14
|
pub inner: dsl::When,
|
9
15
|
}
|
10
16
|
|
11
|
-
|
12
|
-
fn from(inner: dsl::When) -> Self {
|
13
|
-
RbWhen { inner }
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
#[magnus::wrap(class = "Polars::RbWhenThen")]
|
17
|
+
#[magnus::wrap(class = "Polars::RbThen")]
|
18
18
|
#[derive(Clone)]
|
19
19
|
pub struct RbThen {
|
20
20
|
pub inner: dsl::Then,
|
21
21
|
}
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
#[magnus::wrap(class = "Polars::RbChainedWhen")]
|
24
|
+
#[derive(Clone)]
|
25
|
+
pub struct RbChainedWhen {
|
26
|
+
pub inner: dsl::ChainedWhen,
|
27
|
+
}
|
28
|
+
|
29
|
+
#[magnus::wrap(class = "Polars::RbChainedThen")]
|
30
|
+
#[derive(Clone)]
|
31
|
+
pub struct RbChainedThen {
|
32
|
+
pub inner: dsl::ChainedThen,
|
27
33
|
}
|
28
34
|
|
29
35
|
impl RbWhen {
|
30
|
-
pub fn then(&self,
|
31
|
-
|
36
|
+
pub fn then(&self, statement: &RbExpr) -> RbThen {
|
37
|
+
RbThen {
|
38
|
+
inner: self.inner.clone().then(statement.inner.clone()),
|
39
|
+
}
|
32
40
|
}
|
33
41
|
}
|
34
42
|
|
35
43
|
impl RbThen {
|
36
|
-
pub fn
|
37
|
-
|
44
|
+
pub fn when(&self, condition: &RbExpr) -> RbChainedWhen {
|
45
|
+
RbChainedWhen {
|
46
|
+
inner: self.inner.clone().when(condition.inner.clone()),
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
pub fn otherwise(&self, statement: &RbExpr) -> RbExpr {
|
51
|
+
self.inner.clone().otherwise(statement.inner.clone()).into()
|
38
52
|
}
|
39
53
|
}
|
40
54
|
|
41
|
-
|
42
|
-
|
55
|
+
impl RbChainedWhen {
|
56
|
+
pub fn then(&self, statement: &RbExpr) -> RbChainedThen {
|
57
|
+
RbChainedThen {
|
58
|
+
inner: self.inner.clone().then(statement.inner.clone()),
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
impl RbChainedThen {
|
64
|
+
pub fn when(&self, condition: &RbExpr) -> RbChainedWhen {
|
65
|
+
RbChainedWhen {
|
66
|
+
inner: self.inner.clone().when(condition.inner.clone()),
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
pub fn otherwise(&self, statement: &RbExpr) -> RbExpr {
|
71
|
+
self.inner.clone().otherwise(statement.inner.clone()).into()
|
72
|
+
}
|
43
73
|
}
|