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/range.rs
8430 views
1
use polars_ops::series::ClosedInterval;
2
#[cfg(feature = "temporal")]
3
use polars_time::ClosedWindow;
4
5
use super::*;
6
7
/// Generate a range of integers.
8
///
9
/// Alias for `int_range`.
10
pub fn arange(start: Expr, end: Expr, step: i64, dtype: DataType) -> Expr {
11
int_range(start, end, step, dtype)
12
}
13
14
/// Generate a range of integers.
15
pub fn int_range(start: Expr, end: Expr, step: i64, dtype: impl Into<DataTypeExpr>) -> Expr {
16
Expr::n_ary(
17
RangeFunction::IntRange {
18
step,
19
dtype: dtype.into(),
20
},
21
vec![start, end],
22
)
23
}
24
25
/// Generate a range of integers for each row of the input columns.
26
pub fn int_ranges(start: Expr, end: Expr, step: Expr, dtype: impl Into<DataTypeExpr>) -> Expr {
27
Expr::n_ary(
28
RangeFunction::IntRanges {
29
dtype: dtype.into(),
30
},
31
vec![start, end, step],
32
)
33
}
34
35
#[cfg(feature = "dtype-date")]
36
/// Create a date range column from `start`, `end`, and `interval`, and expressions.
37
pub fn date_range(
38
start: Option<Expr>,
39
end: Option<Expr>,
40
interval: Option<Duration>,
41
num_samples: Option<Expr>,
42
closed: ClosedWindow,
43
) -> PolarsResult<Expr> {
44
let (input, arg_type) = DateRangeArgs::parse(start, end, interval, num_samples)?;
45
46
polars_ensure!(
47
interval.is_none_or(|i| i.is_full_days()),
48
ComputeError: "`interval` input for `date_range` must consist of full days, got: {:?}", interval.unwrap(),
49
);
50
51
// Only "both" is supported for date_range(start, end, num_samples).
52
polars_ensure!(
53
!(arg_type == DateRangeArgs::StartEndSamples && closed != ClosedWindow::Both),
54
InvalidOperation: "date_range does not support 'left', 'right', or 'none' for the \
55
'closed' parameter when 'start', 'end', and 'num_samples' is provided.",
56
);
57
58
Ok(Expr::n_ary(
59
RangeFunction::DateRange {
60
interval,
61
closed,
62
arg_type,
63
},
64
input,
65
))
66
}
67
68
#[cfg(feature = "dtype-date")]
69
/// Create a column of date ranges from `start`, `end`, `interval`, and `num_samples` expressions.
70
pub fn date_ranges(
71
start: Option<Expr>,
72
end: Option<Expr>,
73
interval: Option<Duration>,
74
num_samples: Option<Expr>,
75
closed: ClosedWindow,
76
) -> PolarsResult<Expr> {
77
let (input, arg_type) = DateRangeArgs::parse(start, end, interval, num_samples)?;
78
79
polars_ensure!(
80
interval.is_none_or(|i| i.is_full_days()),
81
ComputeError: "`interval` input for `date_range` must consist of full days, got: {:?}", interval.unwrap(),
82
);
83
84
// Only "both" is supported for date_ranges(start, end, num_samples).
85
polars_ensure!(
86
!(arg_type == DateRangeArgs::StartEndSamples && closed != ClosedWindow::Both),
87
InvalidOperation: "date_range does not support 'left', 'right', or 'none' for the \
88
'closed' parameter when 'start', 'end', and 'num_samples' is provided.",
89
);
90
91
Ok(Expr::n_ary(
92
RangeFunction::DateRanges {
93
interval,
94
closed,
95
arg_type,
96
},
97
input,
98
))
99
}
100
101
/// Create a datetime range from `start`, `end`, `interval`, and `num_samples` expressions.
102
#[cfg(feature = "dtype-datetime")]
103
pub fn datetime_range(
104
start: Option<Expr>,
105
end: Option<Expr>,
106
interval: Option<Duration>,
107
num_samples: Option<Expr>,
108
closed: ClosedWindow,
109
time_unit: Option<TimeUnit>,
110
time_zone: Option<TimeZone>,
111
) -> PolarsResult<Expr> {
112
let (input, arg_type) = DateRangeArgs::parse(start, end, interval, num_samples)?;
113
Ok(Expr::n_ary(
114
RangeFunction::DatetimeRange {
115
interval,
116
closed,
117
time_unit,
118
time_zone,
119
arg_type,
120
},
121
input,
122
))
123
}
124
125
/// Create a column of datetime ranges from `start`, `end`, `interval`, and `num_samples` expressions.
126
#[cfg(feature = "dtype-datetime")]
127
pub fn datetime_ranges(
128
start: Option<Expr>,
129
end: Option<Expr>,
130
interval: Option<Duration>,
131
num_samples: Option<Expr>,
132
closed: ClosedWindow,
133
time_unit: Option<TimeUnit>,
134
time_zone: Option<TimeZone>,
135
) -> PolarsResult<Expr> {
136
let (input, arg_type) = DateRangeArgs::parse(start, end, interval, num_samples)?;
137
Ok(Expr::n_ary(
138
RangeFunction::DatetimeRanges {
139
interval,
140
closed,
141
time_unit,
142
time_zone,
143
arg_type,
144
},
145
input,
146
))
147
}
148
149
/// Generate a time range.
150
#[cfg(feature = "dtype-time")]
151
pub fn time_range(start: Expr, end: Expr, interval: Duration, closed: ClosedWindow) -> Expr {
152
Expr::n_ary(
153
RangeFunction::TimeRange { interval, closed },
154
vec![start, end],
155
)
156
}
157
158
/// Create a column of time ranges from a `start` and `stop` expression.
159
#[cfg(feature = "dtype-time")]
160
pub fn time_ranges(start: Expr, end: Expr, interval: Duration, closed: ClosedWindow) -> Expr {
161
Expr::n_ary(
162
RangeFunction::TimeRanges { interval, closed },
163
vec![start, end],
164
)
165
}
166
167
/// Generate a series of equally-spaced points.
168
pub fn linear_space(start: Expr, end: Expr, num_samples: Expr, closed: ClosedInterval) -> Expr {
169
Expr::n_ary(
170
RangeFunction::LinearSpace { closed },
171
vec![start, end, num_samples],
172
)
173
}
174
175
/// Create a column of linearly-spaced sequences from 'start', 'end', and 'num_samples' expressions.
176
pub fn linear_spaces(
177
start: Expr,
178
end: Expr,
179
num_samples: Expr,
180
closed: ClosedInterval,
181
as_array: bool,
182
) -> PolarsResult<Expr> {
183
let mut input = Vec::<Expr>::with_capacity(3);
184
input.push(start);
185
input.push(end);
186
let array_width = if as_array {
187
Some(num_samples.extract_usize().map_err(|_| {
188
polars_err!(InvalidOperation: "'as_array' is only valid when 'num_samples' is a constant integer")
189
})?)
190
} else {
191
input.push(num_samples);
192
None
193
};
194
195
Ok(Expr::n_ary(
196
RangeFunction::LinearSpaces {
197
closed,
198
array_width,
199
},
200
input,
201
))
202
}
203
204