Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-python/src/series/comparison.rs
8412 views
1
use polars_compute::decimal::{DEC128_MAX_PREC, dec128_fits};
2
use pyo3::prelude::*;
3
4
use crate::PySeries;
5
use crate::error::PyPolarsErr;
6
use crate::prelude::*;
7
use crate::utils::EnterPolarsExt;
8
9
#[pymethods]
10
impl PySeries {
11
fn eq(&self, py: Python<'_>, rhs: &PySeries) -> PyResult<Self> {
12
py.enter_polars_series(|| self.series.read().equal(&*rhs.series.read()))
13
}
14
15
fn neq(&self, py: Python<'_>, rhs: &PySeries) -> PyResult<Self> {
16
py.enter_polars_series(|| self.series.read().not_equal(&*rhs.series.read()))
17
}
18
19
fn gt(&self, py: Python<'_>, rhs: &PySeries) -> PyResult<Self> {
20
py.enter_polars_series(|| self.series.read().gt(&*rhs.series.read()))
21
}
22
23
fn gt_eq(&self, py: Python<'_>, rhs: &PySeries) -> PyResult<Self> {
24
py.enter_polars_series(|| self.series.read().gt_eq(&*rhs.series.read()))
25
}
26
27
fn lt(&self, py: Python<'_>, rhs: &PySeries) -> PyResult<Self> {
28
py.enter_polars_series(|| self.series.read().lt(&*rhs.series.read()))
29
}
30
31
fn lt_eq(&self, py: Python<'_>, rhs: &PySeries) -> PyResult<Self> {
32
py.enter_polars_series(|| self.series.read().lt_eq(&*rhs.series.read()))
33
}
34
}
35
36
macro_rules! impl_op {
37
($op:ident, $name:ident, $type:ty) => {
38
#[pymethods]
39
impl PySeries {
40
fn $name(&self, py: Python<'_>, rhs: $type) -> PyResult<Self> {
41
py.enter_polars_series(|| self.series.read().$op(rhs))
42
}
43
}
44
};
45
}
46
47
impl_op!(equal, eq_u8, u8);
48
impl_op!(equal, eq_u16, u16);
49
impl_op!(equal, eq_u32, u32);
50
impl_op!(equal, eq_u64, u64);
51
impl_op!(equal, eq_i8, i8);
52
impl_op!(equal, eq_i16, i16);
53
impl_op!(equal, eq_i32, i32);
54
impl_op!(equal, eq_i64, i64);
55
impl_op!(equal, eq_i128, i128);
56
impl_op!(equal, eq_f16, pf16);
57
impl_op!(equal, eq_f32, f32);
58
impl_op!(equal, eq_f64, f64);
59
impl_op!(equal, eq_str, &str);
60
61
impl_op!(not_equal, neq_u8, u8);
62
impl_op!(not_equal, neq_u16, u16);
63
impl_op!(not_equal, neq_u32, u32);
64
impl_op!(not_equal, neq_u64, u64);
65
impl_op!(not_equal, neq_i8, i8);
66
impl_op!(not_equal, neq_i16, i16);
67
impl_op!(not_equal, neq_i32, i32);
68
impl_op!(not_equal, neq_i64, i64);
69
impl_op!(not_equal, neq_i128, i128);
70
impl_op!(not_equal, neq_f16, pf16);
71
impl_op!(not_equal, neq_f32, f32);
72
impl_op!(not_equal, neq_f64, f64);
73
impl_op!(not_equal, neq_str, &str);
74
75
impl_op!(gt, gt_u8, u8);
76
impl_op!(gt, gt_u16, u16);
77
impl_op!(gt, gt_u32, u32);
78
impl_op!(gt, gt_u64, u64);
79
impl_op!(gt, gt_u128, u128);
80
impl_op!(gt, gt_i8, i8);
81
impl_op!(gt, gt_i16, i16);
82
impl_op!(gt, gt_i32, i32);
83
impl_op!(gt, gt_i64, i64);
84
impl_op!(gt, gt_i128, i128);
85
impl_op!(gt, gt_f16, pf16);
86
impl_op!(gt, gt_f32, f32);
87
impl_op!(gt, gt_f64, f64);
88
impl_op!(gt, gt_str, &str);
89
90
impl_op!(gt_eq, gt_eq_u8, u8);
91
impl_op!(gt_eq, gt_eq_u16, u16);
92
impl_op!(gt_eq, gt_eq_u32, u32);
93
impl_op!(gt_eq, gt_eq_u64, u64);
94
impl_op!(gt_eq, gt_eq_i8, i8);
95
impl_op!(gt_eq, gt_eq_i16, i16);
96
impl_op!(gt_eq, gt_eq_i32, i32);
97
impl_op!(gt_eq, gt_eq_i64, i64);
98
impl_op!(gt_eq, gt_eq_i128, i128);
99
impl_op!(gt_eq, gt_eq_f16, pf16);
100
impl_op!(gt_eq, gt_eq_f32, f32);
101
impl_op!(gt_eq, gt_eq_f64, f64);
102
impl_op!(gt_eq, gt_eq_str, &str);
103
104
impl_op!(lt, lt_u8, u8);
105
impl_op!(lt, lt_u16, u16);
106
impl_op!(lt, lt_u32, u32);
107
impl_op!(lt, lt_u64, u64);
108
impl_op!(lt, lt_u128, u128);
109
impl_op!(lt, lt_i8, i8);
110
impl_op!(lt, lt_i16, i16);
111
impl_op!(lt, lt_i32, i32);
112
impl_op!(lt, lt_i64, i64);
113
impl_op!(lt, lt_i128, i128);
114
impl_op!(lt, lt_f16, pf16);
115
impl_op!(lt, lt_f32, f32);
116
impl_op!(lt, lt_f64, f64);
117
impl_op!(lt, lt_str, &str);
118
119
impl_op!(lt_eq, lt_eq_u8, u8);
120
impl_op!(lt_eq, lt_eq_u16, u16);
121
impl_op!(lt_eq, lt_eq_u32, u32);
122
impl_op!(lt_eq, lt_eq_u64, u64);
123
impl_op!(lt_eq, lt_eq_i8, i8);
124
impl_op!(lt_eq, lt_eq_i16, i16);
125
impl_op!(lt_eq, lt_eq_i32, i32);
126
impl_op!(lt_eq, lt_eq_i64, i64);
127
impl_op!(lt_eq, lt_eq_i128, i128);
128
impl_op!(lt_eq, lt_eq_f16, pf16);
129
impl_op!(lt_eq, lt_eq_f32, f32);
130
impl_op!(lt_eq, lt_eq_f64, f64);
131
impl_op!(lt_eq, lt_eq_str, &str);
132
133
struct PyDecimal(i128, usize, usize);
134
135
impl<'a, 'py> FromPyObject<'a, 'py> for PyDecimal {
136
type Error = PyErr;
137
138
fn extract(obj: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
139
if let Ok(val) = obj.extract() {
140
return Ok(PyDecimal(val, DEC128_MAX_PREC, 0));
141
}
142
143
let err = || {
144
Err(PyPolarsErr::from(polars_err!(ComputeError: "overflow in Python Decimal to Polars Decimal conversion")).into())
145
};
146
147
let (sign, digits, exponent) = obj
148
.call_method0("as_tuple")?
149
.extract::<(i8, Vec<u8>, i8)>()?;
150
let mut val = 0_i128;
151
for d in digits {
152
if let Some(v) = val.checked_mul(10).and_then(|val| val.checked_add(d as _)) {
153
val = v;
154
} else {
155
return err();
156
}
157
}
158
let scale = if exponent > 0 {
159
if let Some(v) = val.checked_mul(10_i128.pow((-exponent) as u32)) {
160
val = v;
161
} else {
162
return err();
163
};
164
0_usize
165
} else {
166
(-exponent) as usize
167
};
168
if sign == 1 {
169
val = -val
170
};
171
if dec128_fits(val, DEC128_MAX_PREC) {
172
Ok(PyDecimal(val, DEC128_MAX_PREC, scale))
173
} else {
174
err()
175
}
176
}
177
}
178
179
macro_rules! impl_decimal {
180
($name:ident, $method:ident) => {
181
#[pymethods]
182
impl PySeries {
183
fn $name(&self, py: Python<'_>, rhs: PyDecimal) -> PyResult<Self> {
184
let rhs = Series::new(
185
PlSmallStr::from_static("decimal"),
186
&[AnyValue::Decimal(rhs.0, rhs.1, rhs.2)],
187
);
188
py.enter_polars_series(|| self.series.read().$method(&rhs))
189
}
190
}
191
};
192
}
193
194
impl_decimal!(eq_decimal, equal);
195
impl_decimal!(neq_decimal, not_equal);
196
impl_decimal!(gt_decimal, gt);
197
impl_decimal!(gt_eq_decimal, gt_eq);
198
impl_decimal!(lt_decimal, lt);
199
impl_decimal!(lt_eq_decimal, lt_eq);
200
201