Skip to content

Commit

Permalink
feat: Allow substraction of time dtype columns (#20300)
Browse files Browse the repository at this point in the history
Co-authored-by: ritchie <[email protected]>
  • Loading branch information
ptiza and ritchie46 authored Dec 15, 2024
1 parent da51207 commit 0c2eb01
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
9 changes: 8 additions & 1 deletion crates/polars-core/src/series/implementations/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,14 @@ impl private::PrivateSeries for SeriesWrap<TimeChunked> {
}

fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {
polars_bail!(opq = sub, DataType::Time, rhs.dtype());
let rhs = rhs.time().map_err(|_| polars_err!(InvalidOperation: "cannot subtract a {} dtype with a series of type: {}", self.dtype(), rhs.dtype()))?;

let phys = self
.0
.physical()
.subtract(&rhs.physical().clone().into_series())?;

Ok(phys.into_duration(TimeUnit::Nanoseconds))
}

fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {
Expand Down
1 change: 1 addition & 0 deletions crates/polars-plan/src/plans/aexpr/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ fn get_arithmetic_field(
(_, Duration(_)) | (Duration(_), _) => {
polars_bail!(InvalidOperation: "{} not allowed on {} and {}", op, left_field.dtype, right_type)
},
(Time, Time) => Duration(TimeUnit::Nanoseconds),
(_, Time) | (Time, _) => {
polars_bail!(InvalidOperation: "{} not allowed on {} and {}", op, left_field.dtype, right_type)
},
Expand Down
25 changes: 25 additions & 0 deletions py-polars/tests/unit/operations/arithmetic/test_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,31 @@ def test_date_datetime_sub() -> None:
}


def test_time_time_sub() -> None:
df = pl.DataFrame(
{
"foo": pl.Series([-1, 0, 10]).cast(pl.Datetime("us")),
"bar": pl.Series([1, 0, 1]).cast(pl.Datetime("us")),
}
)

assert df.select(
pl.col("foo").dt.time() - pl.col("bar").dt.time(),
pl.col("bar").dt.time() - pl.col("foo").dt.time(),
).to_dict(as_series=False) == {
"foo": [
timedelta(days=1, microseconds=-2),
timedelta(0),
timedelta(microseconds=9),
],
"bar": [
timedelta(days=-1, microseconds=2),
timedelta(0),
timedelta(microseconds=-9),
],
}


def test_raise_invalid_shape() -> None:
with pytest.raises(InvalidOperationError):
pl.DataFrame([[1, 2], [3, 4]]) * pl.DataFrame([1, 2, 3])
Expand Down

0 comments on commit 0c2eb01

Please sign in to comment.