Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-python/src/series/aggregation.rs
7889 views
1
use DataType::*;
2
use polars::prelude::*;
3
use pyo3::prelude::*;
4
5
use super::PySeries;
6
use crate::conversion::Wrap;
7
use crate::utils::EnterPolarsExt;
8
9
fn scalar_to_py(scalar: PyResult<Scalar>, py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
10
Wrap(scalar?.as_any_value()).into_pyobject(py)
11
}
12
13
#[pymethods]
14
impl PySeries {
15
fn any(&self, py: Python<'_>, ignore_nulls: bool) -> PyResult<Option<bool>> {
16
py.enter_polars(|| {
17
let s = self.series.read();
18
let s = s.bool()?;
19
PolarsResult::Ok(if ignore_nulls {
20
Some(s.any())
21
} else {
22
s.any_kleene()
23
})
24
})
25
}
26
27
fn all(&self, py: Python<'_>, ignore_nulls: bool) -> PyResult<Option<bool>> {
28
py.enter_polars(|| {
29
let s = self.series.read();
30
let s = s.bool()?;
31
PolarsResult::Ok(if ignore_nulls {
32
Some(s.all())
33
} else {
34
s.all_kleene()
35
})
36
})
37
}
38
39
fn arg_max(&self, py: Python) -> PyResult<Option<usize>> {
40
py.enter_polars_ok(|| self.series.read().arg_max())
41
}
42
43
fn arg_min(&self, py: Python) -> PyResult<Option<usize>> {
44
py.enter_polars_ok(|| self.series.read().arg_min())
45
}
46
47
fn min<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
48
scalar_to_py(py.enter_polars(|| self.series.read().min_reduce()), py)
49
}
50
51
fn max<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
52
scalar_to_py(py.enter_polars(|| self.series.read().max_reduce()), py)
53
}
54
55
fn mean<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
56
let s = self.series.read();
57
match s.dtype() {
58
Boolean => scalar_to_py(
59
py.enter_polars(|| s.cast(&DataType::UInt8).unwrap().mean_reduce()),
60
py,
61
),
62
// For non-numeric output types we require mean_reduce.
63
dt if dt.is_temporal() => scalar_to_py(py.enter_polars(|| s.mean_reduce()), py),
64
_ => Ok(s.mean().into_pyobject(py)?),
65
}
66
}
67
68
fn median<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
69
let s = self.series.read();
70
match s.dtype() {
71
Boolean => scalar_to_py(
72
py.enter_polars(|| s.cast(&DataType::UInt8).unwrap().median_reduce()),
73
py,
74
),
75
// For non-numeric output types we require median_reduce.
76
dt if dt.is_temporal() => scalar_to_py(py.enter_polars(|| s.median_reduce()), py),
77
_ => Ok(s.median().into_pyobject(py)?),
78
}
79
}
80
81
fn product<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
82
scalar_to_py(py.enter_polars(|| self.series.read().product()), py)
83
}
84
85
fn quantile<'py>(
86
&self,
87
py: Python<'py>,
88
quantile: f64,
89
interpolation: Wrap<QuantileMethod>,
90
) -> PyResult<Bound<'py, PyAny>> {
91
scalar_to_py(
92
py.enter_polars(|| {
93
self.series
94
.read()
95
.quantile_reduce(quantile, interpolation.0)
96
}),
97
py,
98
)
99
}
100
101
fn std<'py>(&self, py: Python<'py>, ddof: u8) -> PyResult<Bound<'py, PyAny>> {
102
scalar_to_py(py.enter_polars(|| self.series.read().std_reduce(ddof)), py)
103
}
104
105
fn var<'py>(&self, py: Python<'py>, ddof: u8) -> PyResult<Bound<'py, PyAny>> {
106
scalar_to_py(py.enter_polars(|| self.series.read().var_reduce(ddof)), py)
107
}
108
109
fn sum<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
110
scalar_to_py(py.enter_polars(|| self.series.read().sum_reduce()), py)
111
}
112
113
fn first<'py>(&self, py: Python<'py>, ignore_nulls: bool) -> PyResult<Bound<'py, PyAny>> {
114
let result = if ignore_nulls {
115
py.enter_polars_ok(|| self.series.read().first_non_null())
116
} else {
117
py.enter_polars_ok(|| self.series.read().first())
118
};
119
scalar_to_py(result, py)
120
}
121
122
fn last<'py>(&self, py: Python<'py>, ignore_nulls: bool) -> PyResult<Bound<'py, PyAny>> {
123
let result = if ignore_nulls {
124
py.enter_polars_ok(|| self.series.read().last_non_null())
125
} else {
126
py.enter_polars_ok(|| self.series.read().last())
127
};
128
scalar_to_py(result, py)
129
}
130
131
#[cfg(feature = "approx_unique")]
132
fn approx_n_unique(&self, py: Python) -> PyResult<IdxSize> {
133
py.enter_polars(|| self.series.read().approx_n_unique())
134
}
135
136
#[cfg(feature = "bitwise")]
137
fn bitwise_and<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
138
scalar_to_py(py.enter_polars(|| self.series.read().and_reduce()), py)
139
}
140
141
#[cfg(feature = "bitwise")]
142
fn bitwise_or<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
143
scalar_to_py(py.enter_polars(|| self.series.read().or_reduce()), py)
144
}
145
146
#[cfg(feature = "bitwise")]
147
fn bitwise_xor<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
148
scalar_to_py(py.enter_polars(|| self.series.read().xor_reduce()), py)
149
}
150
}
151
152