Skip to content

Commit a668459

Browse files
authored
Warn on no-op rounding for datetimelike dtypes (#62844)
1 parent 98b6af4 commit a668459

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

pandas/core/frame.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11554,6 +11554,15 @@ def _dict_round(df: DataFrame, decimals) -> Iterator[Series]:
1155411554
def _series_round(ser: Series, decimals: int) -> Series:
1155511555
if is_integer_dtype(ser.dtype) or is_float_dtype(ser.dtype):
1155611556
return ser.round(decimals)
11557+
elif isinstance(ser._values, (DatetimeArray, TimedeltaArray, PeriodArray)):
11558+
# GH#57781
11559+
# TODO: also the ArrowDtype analogues?
11560+
warnings.warn(
11561+
"obj.round has no effect with datetime, timedelta, "
11562+
"or period dtypes. Use obj.dt.round(...) instead.",
11563+
UserWarning,
11564+
stacklevel=find_stack_level(),
11565+
)
1155711566
return ser
1155811567

1155911568
nv.validate_round(args, kwargs)

pandas/core/internals/blocks.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,15 @@ def round(self, decimals: int) -> Self:
15141514
Caller is responsible for validating this
15151515
"""
15161516
if not self.is_numeric or self.is_bool:
1517+
if isinstance(self.values, (DatetimeArray, TimedeltaArray, PeriodArray)):
1518+
# GH#57781
1519+
# TODO: also the ArrowDtype analogues?
1520+
warnings.warn(
1521+
"obj.round has no effect with datetime, timedelta, "
1522+
"or period dtypes. Use obj.dt.round(...) instead.",
1523+
UserWarning,
1524+
stacklevel=find_stack_level(),
1525+
)
15171526
return self.copy(deep=False)
15181527
# TODO: round only defined on BaseMaskedArray
15191528
# Series also does this, so would need to fix both places

pandas/tests/frame/methods/test_round.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,16 @@ def test_round_mixed_type(self):
159159
"col3": date_range("20111111", periods=4),
160160
}
161161
)
162-
tm.assert_frame_equal(df.round(), round_0)
163-
tm.assert_frame_equal(df.round(1), df)
162+
msg = "obj.round has no effect with datetime, timedelta, or period dtypes"
163+
with tm.assert_produces_warning(UserWarning, match=msg):
164+
tm.assert_frame_equal(df.round(), round_0)
165+
with tm.assert_produces_warning(UserWarning, match=msg):
166+
tm.assert_frame_equal(df.round(1), df)
164167
tm.assert_frame_equal(df.round({"col1": 1}), df)
165168
tm.assert_frame_equal(df.round({"col1": 0}), round_0)
166169
tm.assert_frame_equal(df.round({"col1": 0, "col2": 1}), round_0)
167-
tm.assert_frame_equal(df.round({"col3": 1}), df)
170+
with tm.assert_produces_warning(UserWarning, match=msg):
171+
tm.assert_frame_equal(df.round({"col3": 1}), df)
168172

169173
def test_round_with_duplicate_columns(self):
170174
# GH#11611

pandas/tests/tools/test_to_datetime.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1963,7 +1963,7 @@ def test_to_datetime_unit_fractional_seconds(self):
19631963
dtype="M8[ns]",
19641964
)
19651965
# GH20455 argument will incur floating point errors but no premature rounding
1966-
result = result.round("ms")
1966+
result = result.dt.round("ms")
19671967
tm.assert_series_equal(result, expected)
19681968

19691969
def test_to_datetime_unit_na_values(self):

0 commit comments

Comments
 (0)