Path: blob/main/crates/polars-python/src/functions/range.rs
7889 views
use polars::lazy::dsl;1use polars_core::with_match_physical_integer_polars_type;2use polars_ops::series::ClosedInterval;3use polars_plan::constants::get_literal_name;4use pyo3::prelude::*;56use crate::error::PyPolarsErr;7use crate::expr::datatype::PyDataTypeExpr;8use crate::prelude::*;9use crate::utils::EnterPolarsExt;10use crate::{PyExpr, PySeries};1112#[pyfunction]13pub fn int_range(start: PyExpr, end: PyExpr, step: i64, dtype: PyDataTypeExpr) -> PyExpr {14let start = start.inner;15let end = end.inner;16let dtype = dtype.inner;17dsl::int_range(start, end, step, dtype).into()18}1920/// Eager version of `int_range` to avoid overhead from the expression engine.21#[pyfunction]22pub fn eager_int_range(23py: Python<'_>,24lower: &Bound<'_, PyAny>,25upper: &Bound<'_, PyAny>,26step: &Bound<'_, PyAny>,27dtype: PyDataTypeExpr,28) -> PyResult<PySeries> {29let dtype = dtype.inner;30let Some(dtype) = dtype.into_literal() else {31return Err(PyPolarsErr::from(32polars_err!(ComputeError: "eager `int_range` cannot be given lazy datatype expression"),33)34.into());35};3637if !dtype.is_integer() {38return Err(PyPolarsErr::from(39polars_err!(SchemaMismatch: "non-integer `dtype` passed to `int_range`: '{}'", dtype),40)41.into());42}4344with_match_physical_integer_polars_type!(dtype, |$T| {45let start_v: <$T as PolarsNumericType>::Native = lower.extract()?;46let end_v: <$T as PolarsNumericType>::Native = upper.extract()?;47let step: i64 = step.extract()?;48py.enter_polars_series(|| new_int_range::<$T>(start_v, end_v, step, get_literal_name()))49})50}5152#[pyfunction]53pub fn int_ranges(54start: PyExpr,55end: PyExpr,56step: PyExpr,57dtype: PyDataTypeExpr,58) -> PyResult<PyExpr> {59let dtype = dtype.inner;60Ok(dsl::int_ranges(start.inner, end.inner, step.inner, dtype).into())61}6263#[pyfunction]64pub fn date_range(65start: PyExpr,66end: PyExpr,67interval: &str,68closed: Wrap<ClosedWindow>,69) -> PyResult<PyExpr> {70let start = start.inner;71let end = end.inner;72let interval = Duration::try_parse(interval).map_err(PyPolarsErr::from)?;73let closed = closed.0;74let out = dsl::date_range(75Some(start),76Some(end),77Some(interval),78None, // TODO: num_samples79closed,80)81.map_err(PyPolarsErr::from)?;82Ok(out.into())83}8485#[pyfunction]86pub fn date_ranges(87start: PyExpr,88end: PyExpr,89interval: &str,90closed: Wrap<ClosedWindow>,91) -> PyResult<PyExpr> {92let start = start.inner;93let end = end.inner;94let interval = Duration::try_parse(interval).map_err(PyPolarsErr::from)?;95let closed = closed.0;96let out = dsl::date_ranges(97Some(start),98Some(end),99Some(interval),100None, // TODO: num_samples101closed,102)103.map_err(PyPolarsErr::from)?;104Ok(out.into())105}106107#[pyfunction]108#[pyo3(signature = (start, end, interval, closed, time_unit, time_zone))]109pub fn datetime_range(110start: PyExpr,111end: PyExpr,112interval: &str,113closed: Wrap<ClosedWindow>,114time_unit: Option<Wrap<TimeUnit>>,115time_zone: Wrap<Option<TimeZone>>,116) -> PyResult<PyExpr> {117let start = start.inner;118let end = end.inner;119let interval = Duration::try_parse(interval).map_err(PyPolarsErr::from)?;120let closed = closed.0;121let time_unit = time_unit.map(|x| x.0);122let time_zone = time_zone.0;123let out = dsl::datetime_range(124Some(start),125Some(end),126Some(interval),127None, // TODO: num_samples128closed,129time_unit,130time_zone,131)132.map_err(PyPolarsErr::from)?;133Ok(out.into())134}135136#[pyfunction]137#[pyo3(signature = (start, end, interval, closed, time_unit, time_zone))]138pub fn datetime_ranges(139start: PyExpr,140end: PyExpr,141interval: &str,142closed: Wrap<ClosedWindow>,143time_unit: Option<Wrap<TimeUnit>>,144time_zone: Wrap<Option<TimeZone>>,145) -> PyResult<PyExpr> {146let start = start.inner;147let end = end.inner;148let interval = Duration::try_parse(interval).map_err(PyPolarsErr::from)?;149let closed = closed.0;150let time_unit = time_unit.map(|x| x.0);151let time_zone = time_zone.0;152let out = dsl::datetime_ranges(153Some(start),154Some(end),155Some(interval),156None, // TODO: num_samples157closed,158time_unit,159time_zone,160)161.map_err(PyPolarsErr::from)?;162Ok(out.into())163}164165#[pyfunction]166pub fn time_range(167start: PyExpr,168end: PyExpr,169every: &str,170closed: Wrap<ClosedWindow>,171) -> PyResult<PyExpr> {172let start = start.inner;173let end = end.inner;174let every = Duration::try_parse(every).map_err(PyPolarsErr::from)?;175let closed = closed.0;176Ok(dsl::time_range(start, end, every, closed).into())177}178179#[pyfunction]180pub fn time_ranges(181start: PyExpr,182end: PyExpr,183every: &str,184closed: Wrap<ClosedWindow>,185) -> PyResult<PyExpr> {186let start = start.inner;187let end = end.inner;188let every = Duration::try_parse(every).map_err(PyPolarsErr::from)?;189let closed = closed.0;190Ok(dsl::time_ranges(start, end, every, closed).into())191}192193#[pyfunction]194pub fn linear_space(195start: PyExpr,196end: PyExpr,197num_samples: PyExpr,198closed: Wrap<ClosedInterval>,199) -> PyResult<PyExpr> {200let start = start.inner;201let end = end.inner;202let num_samples = num_samples.inner;203let closed = closed.0;204Ok(dsl::linear_space(start, end, num_samples, closed).into())205}206207#[pyfunction]208pub fn linear_spaces(209start: PyExpr,210end: PyExpr,211num_samples: PyExpr,212closed: Wrap<ClosedInterval>,213as_array: bool,214) -> PyResult<PyExpr> {215let start = start.inner;216let end = end.inner;217let num_samples = num_samples.inner;218let closed = closed.0;219let out =220dsl::linear_spaces(start, end, num_samples, closed, as_array).map_err(PyPolarsErr::from)?;221Ok(out.into())222}223224225