Skip to content

Commit 262fcfb

Browse files
authored
BUG: Fix .dt.microsecond accessor for pyarrow-backed Series (#59183)
* BUG: Fix .dt.microsecond accessor for pyarrow-backed Series * Add whatsnew entry * Write test
1 parent 236d89b commit 262fcfb

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ Datetimelike
502502
- Bug in :meth:`DatetimeIndex.is_year_start` and :meth:`DatetimeIndex.is_quarter_start` does not raise on Custom business days frequencies bigger then "1C" (:issue:`58664`)
503503
- Bug in :meth:`DatetimeIndex.is_year_start` and :meth:`DatetimeIndex.is_quarter_start` returning ``False`` on double-digit frequencies (:issue:`58523`)
504504
- Bug in :meth:`DatetimeIndex.union` when ``unit`` was non-nanosecond (:issue:`59036`)
505+
- Bug in :meth:`Series.dt.microsecond` producing incorrect results for pyarrow backed :class:`Series`. (:issue:`59154`)
505506
- Bug in setting scalar values with mismatched resolution into arrays with non-nanosecond ``datetime64``, ``timedelta64`` or :class:`DatetimeTZDtype` incorrectly truncating those scalars (:issue:`56410`)
506507

507508
Timedelta

pandas/core/arrays/arrow/array.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2794,7 +2794,10 @@ def _dt_days_in_month(self) -> Self:
27942794

27952795
@property
27962796
def _dt_microsecond(self) -> Self:
2797-
return type(self)(pc.microsecond(self._pa_array))
2797+
# GH 59154
2798+
us = pc.microsecond(self._pa_array)
2799+
ms_to_us = pc.multiply(pc.millisecond(self._pa_array), 1000)
2800+
return type(self)(pc.add(us, ms_to_us))
27982801

27992802
@property
28002803
def _dt_minute(self) -> Self:

pandas/tests/extension/test_arrow.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2437,13 +2437,13 @@ def test_unsupported_dt(data):
24372437
["hour", 3],
24382438
["minute", 4],
24392439
["is_leap_year", False],
2440-
["microsecond", 5],
2440+
["microsecond", 2000],
24412441
["month", 1],
24422442
["nanosecond", 6],
24432443
["quarter", 1],
24442444
["second", 7],
24452445
["date", date(2023, 1, 2)],
2446-
["time", time(3, 4, 7, 5)],
2446+
["time", time(3, 4, 7, 2000)],
24472447
],
24482448
)
24492449
def test_dt_properties(prop, expected):
@@ -2456,7 +2456,7 @@ def test_dt_properties(prop, expected):
24562456
hour=3,
24572457
minute=4,
24582458
second=7,
2459-
microsecond=5,
2459+
microsecond=2000,
24602460
nanosecond=6,
24612461
),
24622462
None,
@@ -2473,6 +2473,28 @@ def test_dt_properties(prop, expected):
24732473
tm.assert_series_equal(result, expected)
24742474

24752475

2476+
@pytest.mark.parametrize("microsecond", [2000, 5, 0])
2477+
def test_dt_microsecond(microsecond):
2478+
# GH 59183
2479+
ser = pd.Series(
2480+
[
2481+
pd.Timestamp(
2482+
year=2024,
2483+
month=7,
2484+
day=7,
2485+
second=5,
2486+
microsecond=microsecond,
2487+
nanosecond=6,
2488+
),
2489+
None,
2490+
],
2491+
dtype=ArrowDtype(pa.timestamp("ns")),
2492+
)
2493+
result = ser.dt.microsecond
2494+
expected = pd.Series([microsecond, None], dtype="int64[pyarrow]")
2495+
tm.assert_series_equal(result, expected)
2496+
2497+
24762498
def test_dt_is_month_start_end():
24772499
ser = pd.Series(
24782500
[

0 commit comments

Comments
 (0)