1
1
use std:: ops:: { Add , AddAssign , Mul } ;
2
2
3
3
use arity:: unary_elementwise_values;
4
+ use arrow:: array:: BooleanArray ;
5
+ use arrow:: bitmap:: MutableBitmap ;
4
6
use num_traits:: { Bounded , One , Zero } ;
5
7
use polars_core:: prelude:: * ;
6
8
use polars_core:: series:: IsSorted ;
90
92
out. with_name ( ca. name ( ) . clone ( ) )
91
93
}
92
94
95
+ fn cum_max_bool ( ca : & BooleanChunked , reverse : bool ) -> BooleanChunked {
96
+ if ca. len ( ) == ca. null_count ( ) {
97
+ return ca. clone ( ) ;
98
+ }
99
+
100
+ let mut out;
101
+ if !reverse {
102
+ // TODO: efficient bitscan.
103
+ let Some ( first_true_idx) = ca. iter ( ) . position ( |x| x == Some ( true ) ) else {
104
+ return ca. clone ( ) ;
105
+ } ;
106
+ out = MutableBitmap :: with_capacity ( ca. len ( ) ) ;
107
+ out. extend_constant ( first_true_idx, false ) ;
108
+ out. extend_constant ( ca. len ( ) - first_true_idx, true ) ;
109
+ } else {
110
+ // TODO: efficient bitscan.
111
+ let Some ( last_true_idx) = ca. iter ( ) . rposition ( |x| x == Some ( true ) ) else {
112
+ return ca. clone ( ) ;
113
+ } ;
114
+ out = MutableBitmap :: with_capacity ( ca. len ( ) ) ;
115
+ out. extend_constant ( last_true_idx + 1 , true ) ;
116
+ out. extend_constant ( ca. len ( ) - 1 - last_true_idx, false ) ;
117
+ }
118
+
119
+ let arr: BooleanArray = out. freeze ( ) . into ( ) ;
120
+ BooleanChunked :: with_chunk_like ( ca, arr. with_validity ( ca. rechunk_validity ( ) ) )
121
+ }
122
+
123
+ fn cum_min_bool ( ca : & BooleanChunked , reverse : bool ) -> BooleanChunked {
124
+ if ca. len ( ) == ca. null_count ( ) {
125
+ return ca. clone ( ) ;
126
+ }
127
+
128
+ let mut out;
129
+ if !reverse {
130
+ // TODO: efficient bitscan.
131
+ let Some ( first_false_idx) = ca. iter ( ) . position ( |x| x == Some ( false ) ) else {
132
+ return ca. clone ( ) ;
133
+ } ;
134
+ out = MutableBitmap :: with_capacity ( ca. len ( ) ) ;
135
+ out. extend_constant ( first_false_idx, true ) ;
136
+ out. extend_constant ( ca. len ( ) - first_false_idx, false ) ;
137
+ } else {
138
+ // TODO: efficient bitscan.
139
+ let Some ( last_false_idx) = ca. iter ( ) . rposition ( |x| x == Some ( false ) ) else {
140
+ return ca. clone ( ) ;
141
+ } ;
142
+ out = MutableBitmap :: with_capacity ( ca. len ( ) ) ;
143
+ out. extend_constant ( last_false_idx + 1 , false ) ;
144
+ out. extend_constant ( ca. len ( ) - 1 - last_false_idx, true ) ;
145
+ }
146
+
147
+ let arr: BooleanArray = out. freeze ( ) . into ( ) ;
148
+ BooleanChunked :: with_chunk_like ( ca, arr. with_validity ( ca. rechunk_validity ( ) ) )
149
+ }
150
+
93
151
fn cum_sum_numeric < T > ( ca : & ChunkedArray < T > , reverse : bool ) -> ChunkedArray < T >
94
152
where
95
153
T : PolarsNumericType ,
@@ -173,13 +231,14 @@ pub fn cum_min(s: &Series, reverse: bool) -> PolarsResult<Series> {
173
231
let original_type = s. dtype ( ) ;
174
232
let s = s. to_physical_repr ( ) ;
175
233
match s. dtype ( ) {
234
+ DataType :: Boolean => Ok ( cum_min_bool ( s. bool ( ) ?, reverse) . into_series ( ) ) ,
176
235
dt if dt. is_numeric ( ) => {
177
236
with_match_physical_numeric_polars_type ! ( s. dtype( ) , |$T | {
178
237
let ca: & ChunkedArray <$T > = s. as_ref( ) . as_ref( ) . as_ref( ) ;
179
238
let out = cum_min_numeric( ca, reverse) . into_series( ) ;
180
- if original_type. is_logical( ) {
239
+ if original_type. is_logical( ) {
181
240
out. cast( original_type)
182
- } else{
241
+ } else {
183
242
Ok ( out)
184
243
}
185
244
} )
@@ -193,13 +252,14 @@ pub fn cum_max(s: &Series, reverse: bool) -> PolarsResult<Series> {
193
252
let original_type = s. dtype ( ) ;
194
253
let s = s. to_physical_repr ( ) ;
195
254
match s. dtype ( ) {
255
+ DataType :: Boolean => Ok ( cum_max_bool ( s. bool ( ) ?, reverse) . into_series ( ) ) ,
196
256
dt if dt. is_numeric ( ) => {
197
257
with_match_physical_numeric_polars_type ! ( s. dtype( ) , |$T | {
198
258
let ca: & ChunkedArray <$T > = s. as_ref( ) . as_ref( ) . as_ref( ) ;
199
259
let out = cum_max_numeric( ca, reverse) . into_series( ) ;
200
- if original_type. is_logical( ) {
260
+ if original_type. is_logical( ) {
201
261
out. cast( original_type)
202
- } else{
262
+ } else {
203
263
Ok ( out)
204
264
}
205
265
} )
0 commit comments