Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-expr/src/dispatch/range/int_range.rs
7884 views
1
use polars_core::prelude::*;
2
use polars_core::with_match_physical_integer_polars_type;
3
use polars_ops::series::new_int_range;
4
5
use super::utils::{ensure_items_contain_exactly_one_value, numeric_ranges_impl_broadcast};
6
7
const CAPACITY_FACTOR: usize = 5;
8
9
pub(super) fn int_range(s: &[Column], step: i64, dtype: DataType) -> PolarsResult<Column> {
10
let start = &s[0];
11
let end = &s[1];
12
let name = start.name();
13
14
ensure_items_contain_exactly_one_value(&[start, end], &["start", "end"])?;
15
16
// Done by type coercion
17
assert!(dtype.is_integer());
18
assert_eq!(start.dtype(), &dtype);
19
assert_eq!(end.dtype(), &dtype);
20
21
with_match_physical_integer_polars_type!(dtype, |$T| {
22
let start_v = get_first_series_value::<$T>(start)?;
23
let end_v = get_first_series_value::<$T>(end)?;
24
new_int_range::<$T>(start_v, end_v, step, name.clone()).map(Column::from)
25
})
26
}
27
28
fn get_first_series_value<T>(s: &Column) -> PolarsResult<T::Native>
29
where
30
T: PolarsIntegerType,
31
{
32
let ca: &ChunkedArray<T> = s.as_materialized_series().as_any().downcast_ref().unwrap();
33
let value_opt = ca.get(0);
34
let value =
35
value_opt.ok_or_else(|| polars_err!(ComputeError: "invalid null input for `int_range`"))?;
36
Ok(value)
37
}
38
39
pub(super) fn int_ranges(s: &[Column], dtype: DataType) -> PolarsResult<Column> {
40
let start = &s[0];
41
let end = &s[1];
42
let step = &s[2];
43
44
let start = start.i64()?;
45
let end = end.i64()?;
46
let step = step.i64()?;
47
48
let len = std::cmp::max(start.len(), end.len());
49
let mut builder = ListPrimitiveChunkedBuilder::<Int64Type>::new(
50
// The name should follow our left hand rule.
51
start.name().clone(),
52
len,
53
len * CAPACITY_FACTOR,
54
DataType::Int64,
55
);
56
57
let range_impl =
58
|start, end, step: i64, builder: &mut ListPrimitiveChunkedBuilder<Int64Type>| {
59
match step {
60
1 => builder.append_values_iter_trusted_len(start..end),
61
2.. => builder.append_values_iter_trusted_len((start..end).step_by(step as usize)),
62
_ => builder.append_values_iter_trusted_len(
63
(end..start)
64
.step_by(step.unsigned_abs() as usize)
65
.map(|x| start - (x - end)),
66
),
67
};
68
Ok(())
69
};
70
71
let column = numeric_ranges_impl_broadcast(start, end, step, range_impl, &mut builder)?;
72
73
if dtype != DataType::Int64 {
74
column.cast(&DataType::List(Box::new(dtype)))
75
} else {
76
Ok(column)
77
}
78
}
79
80