Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-plan/src/dsl/functions/horizontal.rs
8433 views
1
use super::*;
2
use crate::prelude::PlanCallback;
3
4
/// Accumulate over multiple columns horizontally / row wise.
5
pub fn fold_exprs<E>(
6
acc: Expr,
7
f: PlanCallback<(Series, Series), Series>,
8
exprs: E,
9
returns_scalar: bool,
10
return_dtype: Option<DataTypeExpr>,
11
) -> Expr
12
where
13
E: AsRef<[Expr]>,
14
{
15
let mut exprs_v = Vec::with_capacity(exprs.as_ref().len() + 1);
16
exprs_v.push(acc);
17
exprs_v.extend(exprs.as_ref().iter().cloned());
18
19
Expr::Function {
20
input: exprs_v,
21
function: FunctionExpr::FoldHorizontal {
22
callback: f,
23
returns_scalar,
24
return_dtype,
25
},
26
}
27
}
28
29
/// Analogous to [`Iterator::reduce`](std::iter::Iterator::reduce).
30
///
31
/// An accumulator is initialized to the series given by the first expression in `exprs`, and then each subsequent value
32
/// of the accumulator is computed from `f(acc, next_expr_series)`. If `exprs` is empty, an error is returned when
33
/// `collect` is called.
34
pub fn reduce_exprs<E>(
35
f: PlanCallback<(Series, Series), Series>,
36
exprs: E,
37
returns_scalar: bool,
38
return_dtype: Option<DataTypeExpr>,
39
) -> Expr
40
where
41
E: AsRef<[Expr]>,
42
{
43
let exprs = exprs.as_ref().to_vec();
44
45
Expr::Function {
46
input: exprs,
47
function: FunctionExpr::ReduceHorizontal {
48
callback: f,
49
returns_scalar,
50
return_dtype,
51
},
52
}
53
}
54
55
/// Accumulate over multiple columns horizontally / row wise.
56
#[cfg(feature = "dtype-struct")]
57
pub fn cum_reduce_exprs<E>(
58
f: PlanCallback<(Series, Series), Series>,
59
exprs: E,
60
61
returns_scalar: bool,
62
return_dtype: Option<DataTypeExpr>,
63
) -> Expr
64
where
65
E: AsRef<[Expr]>,
66
{
67
let exprs = exprs.as_ref().to_vec();
68
69
Expr::Function {
70
input: exprs,
71
function: FunctionExpr::CumReduceHorizontal {
72
callback: f,
73
returns_scalar,
74
return_dtype,
75
},
76
}
77
}
78
79
/// Accumulate over multiple columns horizontally / row wise.
80
#[cfg(feature = "dtype-struct")]
81
pub fn cum_fold_exprs<E>(
82
acc: Expr,
83
f: PlanCallback<(Series, Series), Series>,
84
exprs: E,
85
returns_scalar: bool,
86
return_dtype: Option<DataTypeExpr>,
87
include_init: bool,
88
) -> Expr
89
where
90
E: AsRef<[Expr]>,
91
{
92
let exprs = exprs.as_ref();
93
let mut exprs_v = Vec::with_capacity(exprs.len());
94
exprs_v.push(acc);
95
exprs_v.extend(exprs.iter().cloned());
96
97
Expr::Function {
98
input: exprs_v,
99
function: FunctionExpr::CumFoldHorizontal {
100
callback: f,
101
returns_scalar,
102
return_dtype,
103
include_init,
104
},
105
}
106
}
107
108
/// Create a new column with the bitwise-and of the elements in each row.
109
///
110
/// The name of the resulting column will be "all"; use [`alias`](Expr::alias) to choose a different name.
111
pub fn all_horizontal<E: AsRef<[Expr]>>(exprs: E) -> PolarsResult<Expr> {
112
let exprs = exprs.as_ref().to_vec();
113
polars_ensure!(!exprs.is_empty(), ComputeError: "cannot return empty fold because the number of output rows is unknown");
114
// This will be reduced to `expr & expr` during conversion to IR.
115
Ok(Expr::n_ary(
116
FunctionExpr::Boolean(BooleanFunction::AllHorizontal),
117
exprs,
118
))
119
}
120
121
/// Create a new column with the bitwise-or of the elements in each row.
122
///
123
/// The name of the resulting column will be "any"; use [`alias`](Expr::alias) to choose a different name.
124
pub fn any_horizontal<E: AsRef<[Expr]>>(exprs: E) -> PolarsResult<Expr> {
125
let exprs = exprs.as_ref().to_vec();
126
polars_ensure!(!exprs.is_empty(), ComputeError: "cannot return empty fold because the number of output rows is unknown");
127
// This will be reduced to `expr | expr` during conversion to IR.
128
Ok(Expr::n_ary(
129
FunctionExpr::Boolean(BooleanFunction::AnyHorizontal),
130
exprs,
131
))
132
}
133
134
/// Create a new column with the maximum value per row.
135
///
136
/// The name of the resulting column will be `"max"`; use [`alias`](Expr::alias) to choose a different name.
137
pub fn max_horizontal<E: AsRef<[Expr]>>(exprs: E) -> PolarsResult<Expr> {
138
let exprs = exprs.as_ref().to_vec();
139
polars_ensure!(!exprs.is_empty(), ComputeError: "cannot return empty fold because the number of output rows is unknown");
140
Ok(Expr::n_ary(FunctionExpr::MaxHorizontal, exprs))
141
}
142
143
/// Create a new column with the minimum value per row.
144
///
145
/// The name of the resulting column will be `"min"`; use [`alias`](Expr::alias) to choose a different name.
146
pub fn min_horizontal<E: AsRef<[Expr]>>(exprs: E) -> PolarsResult<Expr> {
147
let exprs = exprs.as_ref().to_vec();
148
polars_ensure!(!exprs.is_empty(), ComputeError: "cannot return empty fold because the number of output rows is unknown");
149
Ok(Expr::n_ary(FunctionExpr::MinHorizontal, exprs))
150
}
151
152
/// Sum all values horizontally across columns.
153
pub fn sum_horizontal<E: AsRef<[Expr]>>(exprs: E, ignore_nulls: bool) -> PolarsResult<Expr> {
154
let exprs = exprs.as_ref().to_vec();
155
polars_ensure!(!exprs.is_empty(), ComputeError: "cannot return empty fold because the number of output rows is unknown");
156
Ok(Expr::n_ary(
157
FunctionExpr::SumHorizontal { ignore_nulls },
158
exprs,
159
))
160
}
161
162
/// Compute the mean of all values horizontally across columns.
163
pub fn mean_horizontal<E: AsRef<[Expr]>>(exprs: E, ignore_nulls: bool) -> PolarsResult<Expr> {
164
let exprs = exprs.as_ref().to_vec();
165
polars_ensure!(!exprs.is_empty(), ComputeError: "cannot return empty fold because the number of output rows is unknown");
166
Ok(Expr::n_ary(
167
FunctionExpr::MeanHorizontal { ignore_nulls },
168
exprs,
169
))
170
}
171
172
/// Folds the expressions from left to right keeping the first non-null values.
173
///
174
/// It is an error to provide an empty `exprs`.
175
pub fn coalesce(exprs: &[Expr]) -> Expr {
176
Expr::n_ary(FunctionExpr::Coalesce, exprs.to_vec())
177
}
178
179