Skip to content

Commit

Permalink
Python series: min/max logical types (#3191)
Browse files Browse the repository at this point in the history
Co-authored-by: Colin Jermain <cjermain@users.noreply.github.com>
  • Loading branch information
ritchie46 and cjermain committed Apr 20, 2022
1 parent 8b2db30 commit aa03cac
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 33 deletions.
19 changes: 10 additions & 9 deletions py-polars/polars/internals/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -4672,28 +4672,29 @@ def timestamp(self, tu: str = "us") -> Series:
def to_python_datetime(self) -> Series:
"""
Go from Date/Datetime to python DateTime objects
.. deprecated:: 0.13.23
Use :func:`Series.to_list`.
"""
return (self.timestamp("ms") / 1000).apply(
lambda ts: datetime.utcfromtimestamp(ts), Object
)

def min(self) -> Union[date, datetime]:
def min(self) -> Union[date, datetime, timedelta]:
"""
Return minimum as python DateTime
"""
s = wrap_s(self._s)
out = s.min()
return _to_python_datetime(out, s.dtype, s.time_unit)
# we can ignore types because we are certain we get a logical type
return wrap_s(self._s).min() # type: ignore

def max(self) -> Union[date, datetime]:
def max(self) -> Union[date, datetime, timedelta]:
"""
Return maximum as python DateTime
"""
s = wrap_s(self._s)
out = s.max()
return _to_python_datetime(out, s.dtype, s.time_unit)
return wrap_s(self._s).max() # type: ignore

def median(self) -> Union[date, datetime]:
def median(self) -> Union[date, datetime, timedelta]:
"""
Return median as python DateTime
"""
Expand Down
30 changes: 6 additions & 24 deletions py-polars/src/series.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,34 +396,16 @@ impl PySeries {
}
}

pub fn max(&self) -> PyObject {
let gil = Python::acquire_gil();
let py = gil.python();
match self.series.dtype() {
DataType::Float32 | DataType::Float64 => self.series.max::<f64>().to_object(py),
DataType::Boolean => self.series.max::<u32>().map(|v| v == 1).to_object(py),
_ => self.series.max::<i64>().to_object(py),
}
pub fn max(&self, py: Python) -> PyObject {
Wrap(self.series.max_as_series().get(0)).into_py(py)
}

pub fn min(&self) -> PyObject {
let gil = Python::acquire_gil();
let py = gil.python();
match self.series.dtype() {
DataType::Float32 | DataType::Float64 => self.series.min::<f64>().to_object(py),
DataType::Boolean => self.series.min::<u32>().map(|v| v == 1).to_object(py),
_ => self.series.min::<i64>().to_object(py),
}
pub fn min(&self, py: Python) -> PyObject {
Wrap(self.series.min_as_series().get(0)).into_py(py)
}

pub fn sum(&self) -> PyObject {
let gil = Python::acquire_gil();
let py = gil.python();
match self.series.dtype() {
DataType::Float32 | DataType::Float64 => self.series.sum::<f64>().to_object(py),
DataType::Boolean => self.series.sum::<u64>().to_object(py),
_ => self.series.sum::<i64>().to_object(py),
}
pub fn sum(&self, py: Python) -> PyObject {
Wrap(self.series.sum_as_series().get(0)).into_py(py)
}

pub fn n_chunks(&self) -> usize {
Expand Down
7 changes: 7 additions & 0 deletions py-polars/tests/test_datelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -827,3 +827,10 @@ def test_duration_filter() -> None:

assert date_df.filter(pl.col("time_passed") < timedelta(days=30)).shape[0] == 1
assert date_df.filter(pl.col("time_passed") >= timedelta(days=30)).shape[0] == 2


def test_agg_logical() -> None:
dates = [date(2001, 1, 1), date(2002, 1, 1)]
s = pl.Series(dates)
assert s.max() == dates[1]
assert s.min() == dates[0]

0 comments on commit aa03cac

Please sign in to comment.