diff --git a/narwhals/_pandas_like/series.py b/narwhals/_pandas_like/series.py index f2589f0e5..b4631bbf7 100644 --- a/narwhals/_pandas_like/series.py +++ b/narwhals/_pandas_like/series.py @@ -867,8 +867,19 @@ def ordinal_day(self) -> PandasLikeSeries: ) ) + def _get_total_seconds(self) -> Any: + if hasattr(self._pandas_series._native_series.dt, "total_seconds"): + return self._pandas_series._native_series.dt.total_seconds() + else: # pragma: no cover + return ( + self._pandas_series._native_series.dt.days * 86400 + + self._pandas_series._native_series.dt.seconds + + (self._pandas_series._native_series.dt.microseconds / 1e6) + + (self._pandas_series._native_series.dt.nanoseconds / 1e9) + ) + def total_minutes(self) -> PandasLikeSeries: - s = self._pandas_series._native_series.dt.total_seconds() + s = self._get_total_seconds() s_sign = ( 2 * (s > 0).astype(int_dtype_mapper(s.dtype)) - 1 ) # this calculates the sign of each series element @@ -878,7 +889,7 @@ def total_minutes(self) -> PandasLikeSeries: return self._pandas_series._from_native_series(s_abs * s_sign) def total_seconds(self) -> PandasLikeSeries: - s = self._pandas_series._native_series.dt.total_seconds() + s = self._get_total_seconds() s_sign = ( 2 * (s > 0).astype(int_dtype_mapper(s.dtype)) - 1 ) # this calculates the sign of each series element @@ -888,7 +899,7 @@ def total_seconds(self) -> PandasLikeSeries: return self._pandas_series._from_native_series(s_abs * s_sign) def total_milliseconds(self) -> PandasLikeSeries: - s = self._pandas_series._native_series.dt.total_seconds() * 1e3 + s = self._get_total_seconds() * 1e3 s_sign = ( 2 * (s > 0).astype(int_dtype_mapper(s.dtype)) - 1 ) # this calculates the sign of each series element @@ -898,7 +909,7 @@ def total_milliseconds(self) -> PandasLikeSeries: return self._pandas_series._from_native_series(s_abs * s_sign) def total_microseconds(self) -> PandasLikeSeries: - s = self._pandas_series._native_series.dt.total_seconds() * 1e6 + s = self._get_total_seconds() * 1e6 s_sign = ( 2 * (s > 0).astype(int_dtype_mapper(s.dtype)) - 1 ) # this calculates the sign of each series element @@ -908,7 +919,7 @@ def total_microseconds(self) -> PandasLikeSeries: return self._pandas_series._from_native_series(s_abs * s_sign) def total_nanoseconds(self) -> PandasLikeSeries: - s = self._pandas_series._native_series.dt.total_seconds() * 1e9 + s = self._get_total_seconds() * 1e9 s_sign = ( 2 * (s > 0).astype(int_dtype_mapper(s.dtype)) - 1 ) # this calculates the sign of each series element diff --git a/tests/expr_and_series/dt/datetime_duration_test.py b/tests/expr_and_series/dt/datetime_duration_test.py index 9a93591c9..09f227c79 100644 --- a/tests/expr_and_series/dt/datetime_duration_test.py +++ b/tests/expr_and_series/dt/datetime_duration_test.py @@ -46,8 +46,6 @@ def test_duration_attributes( ) -> None: if PANDAS_VERSION < (2, 2) and "pandas_pyarrow" in str(constructor): request.applymarker(pytest.mark.xfail) - if "cudf" in str(constructor): - request.applymarker(pytest.mark.xfail) df = nw.from_native(constructor(data)) @@ -81,8 +79,6 @@ def test_duration_attributes_series( ) -> None: if PANDAS_VERSION < (2, 2) and "pandas_pyarrow" in str(constructor_eager): request.applymarker(pytest.mark.xfail) - if "cudf" in str(constructor_eager): - request.applymarker(pytest.mark.xfail) df = nw.from_native(constructor_eager(data), eager_only=True)