Skip to content

Commit 0a7477b

Browse files
authored
BUG: Index.view with non-nano (#55710)
* BUG: Index.view with non-nano * GH ref
1 parent ccca5df commit 0a7477b

File tree

4 files changed

+36
-20
lines changed

4 files changed

+36
-20
lines changed

doc/source/whatsnew/v2.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ Datetimelike
322322
^^^^^^^^^^^^
323323
- Bug in :func:`concat` raising ``AttributeError`` when concatenating all-NA DataFrame with :class:`DatetimeTZDtype` dtype DataFrame. (:issue:`52093`)
324324
- Bug in :meth:`DatetimeIndex.union` returning object dtype for tz-aware indexes with the same timezone but different units (:issue:`55238`)
325+
- Bug in :meth:`Index.view` to a datetime64 dtype with non-supported resolution incorrectly raising (:issue:`55710`)
325326
- Bug in :meth:`Tick.delta` with very large ticks raising ``OverflowError`` instead of ``OutOfBoundsTimedelta`` (:issue:`55503`)
326327
- Bug in adding or subtracting a :class:`Week` offset to a ``datetime64`` :class:`Series`, :class:`Index`, or :class:`DataFrame` column with non-nanosecond resolution returning incorrect results (:issue:`55583`)
327328
- Bug in addition or subtraction of :class:`BusinessDay` offset with ``offset`` attribute to non-nanosecond :class:`Index`, :class:`Series`, or :class:`DataFrame` column giving incorrect results (:issue:`55608`)

pandas/core/arrays/_mixins.py

+12-10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
from pandas._libs import lib
1515
from pandas._libs.arrays import NDArrayBacked
16+
from pandas._libs.tslibs import (
17+
get_unit_from_dtype,
18+
is_supported_unit,
19+
)
1620
from pandas._typing import (
1721
ArrayLike,
1822
AxisInt,
@@ -137,21 +141,19 @@ def view(self, dtype: Dtype | None = None) -> ArrayLike:
137141
cls = dtype.construct_array_type() # type: ignore[assignment]
138142
dt64_values = arr.view(f"M8[{dtype.unit}]")
139143
return cls(dt64_values, dtype=dtype)
140-
elif dtype == "M8[ns]":
144+
elif lib.is_np_dtype(dtype, "M") and is_supported_unit(
145+
get_unit_from_dtype(dtype)
146+
):
141147
from pandas.core.arrays import DatetimeArray
142148

143-
# error: Argument 1 to "view" of "ndarray" has incompatible type
144-
# "ExtensionDtype | dtype[Any]"; expected "dtype[Any] | type[Any]
145-
# | _SupportsDType[dtype[Any]]"
146-
dt64_values = arr.view(dtype) # type: ignore[arg-type]
149+
dt64_values = arr.view(dtype)
147150
return DatetimeArray(dt64_values, dtype=dtype)
148-
elif dtype == "m8[ns]":
151+
elif lib.is_np_dtype(dtype, "m") and is_supported_unit(
152+
get_unit_from_dtype(dtype)
153+
):
149154
from pandas.core.arrays import TimedeltaArray
150155

151-
# error: Argument 1 to "view" of "ndarray" has incompatible type
152-
# "ExtensionDtype | dtype[Any]"; expected "dtype[Any] | type[Any]
153-
# | _SupportsDType[dtype[Any]]"
154-
td64_values = arr.view(dtype) # type: ignore[arg-type]
156+
td64_values = arr.view(dtype)
155157
return TimedeltaArray(td64_values, dtype=dtype)
156158

157159
# error: Argument "dtype" to "view" of "_ArrayOrScalarCommon" has incompatible

pandas/core/indexes/base.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -999,17 +999,14 @@ def view(self, cls=None):
999999
dtype = pandas_dtype(cls)
10001000

10011001
if needs_i8_conversion(dtype):
1002-
if dtype.kind == "m" and dtype != "m8[ns]":
1003-
# e.g. m8[s]
1004-
return self._data.view(cls)
1005-
10061002
idx_cls = self._dtype_to_subclass(dtype)
1007-
# NB: we only get here for subclasses that override
1008-
# _data_cls such that it is a type and not a tuple
1009-
# of types.
1010-
arr_cls = idx_cls._data_cls
1011-
arr = arr_cls(self._data.view("i8"), dtype=dtype)
1012-
return idx_cls._simple_new(arr, name=self.name, refs=self._references)
1003+
arr = self.array.view(dtype)
1004+
if isinstance(arr, ExtensionArray):
1005+
# here we exclude non-supported dt64/td64 dtypes
1006+
return idx_cls._simple_new(
1007+
arr, name=self.name, refs=self._references
1008+
)
1009+
return arr
10131010

10141011
result = self._data.view(cls)
10151012
else:

pandas/tests/indexes/numeric/test_numeric.py

+16
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,19 @@ def test_map_dtype_inference_overflows():
527527
# TODO: we could plausibly try to infer down to int16 here
528528
expected = Index([1000, 2000, 3000], dtype=np.int64)
529529
tm.assert_index_equal(result, expected)
530+
531+
532+
def test_view_to_datetimelike():
533+
# GH#55710
534+
idx = Index([1, 2, 3])
535+
res = idx.view("m8[s]")
536+
expected = pd.TimedeltaIndex(idx.values.view("m8[s]"))
537+
tm.assert_index_equal(res, expected)
538+
539+
res2 = idx.view("m8[D]")
540+
expected2 = idx.values.view("m8[D]")
541+
tm.assert_numpy_array_equal(res2, expected2)
542+
543+
res3 = idx.view("M8[h]")
544+
expected3 = idx.values.view("M8[h]")
545+
tm.assert_numpy_array_equal(res3, expected3)

0 commit comments

Comments
 (0)