Skip to content

Commit f4ca4d3

Browse files
authored
ENH: DatetimeIndex.snap support non-nano (#47537)
1 parent ad842d3 commit f4ca4d3

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

pandas/core/indexes/datetimes.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
from pandas.util._exceptions import find_stack_level
4747

4848
from pandas.core.dtypes.common import (
49-
DT64NS_DTYPE,
5049
is_datetime64_dtype,
5150
is_datetime64tz_dtype,
5251
is_scalar,
@@ -566,7 +565,7 @@ def snap(self, freq="S") -> DatetimeIndex:
566565
# Superdumb, punting on any optimizing
567566
freq = to_offset(freq)
568567

569-
snapped = np.empty(len(self), dtype=DT64NS_DTYPE)
568+
dta = self._data.copy()
570569

571570
for i, v in enumerate(self):
572571
s = v
@@ -577,9 +576,8 @@ def snap(self, freq="S") -> DatetimeIndex:
577576
s = t0
578577
else:
579578
s = t1
580-
snapped[i] = s
579+
dta[i] = s
581580

582-
dta = DatetimeArray(snapped, dtype=self.dtype)
583581
return DatetimeIndex._simple_new(dta, name=self.name)
584582

585583
# --------------------------------------------------------------------

pandas/tests/indexes/datetimes/methods/test_snap.py

+24-1
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,30 @@
77
import pandas._testing as tm
88

99

10+
def astype_non_nano(dti_nano, unit):
11+
# TODO(2.0): remove once DTI/DTA.astype supports non-nano
12+
if unit == "ns":
13+
return dti_nano
14+
15+
dta_nano = dti_nano._data
16+
arr_nano = dta_nano._ndarray
17+
18+
arr = arr_nano.astype(f"M8[{unit}]")
19+
if dti_nano.tz is None:
20+
dtype = arr.dtype
21+
else:
22+
dtype = type(dti_nano.dtype)(tz=dti_nano.tz, unit=unit)
23+
dta = type(dta_nano)._simple_new(arr, dtype=dtype)
24+
dti = DatetimeIndex(dta, name=dti_nano.name)
25+
assert dti.dtype == dtype
26+
return dti
27+
28+
1029
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
1130
@pytest.mark.parametrize("tz", [None, "Asia/Shanghai", "Europe/Berlin"])
1231
@pytest.mark.parametrize("name", [None, "my_dti"])
13-
def test_dti_snap(name, tz):
32+
@pytest.mark.parametrize("unit", ["ns", "us", "ms", "s"])
33+
def test_dti_snap(name, tz, unit):
1434
dti = DatetimeIndex(
1535
[
1636
"1/1/2002",
@@ -25,10 +45,12 @@ def test_dti_snap(name, tz):
2545
tz=tz,
2646
freq="D",
2747
)
48+
dti = astype_non_nano(dti, unit)
2849

2950
result = dti.snap(freq="W-MON")
3051
expected = date_range("12/31/2001", "1/7/2002", name=name, tz=tz, freq="w-mon")
3152
expected = expected.repeat([3, 4])
53+
expected = astype_non_nano(expected, unit)
3254
tm.assert_index_equal(result, expected)
3355
assert result.tz == expected.tz
3456
assert result.freq is None
@@ -38,6 +60,7 @@ def test_dti_snap(name, tz):
3860

3961
expected = date_range("1/1/2002", "1/7/2002", name=name, tz=tz, freq="b")
4062
expected = expected.repeat([1, 1, 1, 2, 2])
63+
expected = astype_non_nano(expected, unit)
4164
tm.assert_index_equal(result, expected)
4265
assert result.tz == expected.tz
4366
assert result.freq is None

0 commit comments

Comments
 (0)