Skip to content

Commit

Permalink
BUG: Index.view with non-nano (#55710)
Browse files Browse the repository at this point in the history
* BUG: Index.view with non-nano

* GH ref
  • Loading branch information
jbrockmendel authored Oct 27, 2023
1 parent ccca5df commit 0a7477b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 20 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ Datetimelike
^^^^^^^^^^^^
- Bug in :func:`concat` raising ``AttributeError`` when concatenating all-NA DataFrame with :class:`DatetimeTZDtype` dtype DataFrame. (:issue:`52093`)
- Bug in :meth:`DatetimeIndex.union` returning object dtype for tz-aware indexes with the same timezone but different units (:issue:`55238`)
- Bug in :meth:`Index.view` to a datetime64 dtype with non-supported resolution incorrectly raising (:issue:`55710`)
- Bug in :meth:`Tick.delta` with very large ticks raising ``OverflowError`` instead of ``OutOfBoundsTimedelta`` (:issue:`55503`)
- 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`)
- 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`)
Expand Down
22 changes: 12 additions & 10 deletions pandas/core/arrays/_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

from pandas._libs import lib
from pandas._libs.arrays import NDArrayBacked
from pandas._libs.tslibs import (
get_unit_from_dtype,
is_supported_unit,
)
from pandas._typing import (
ArrayLike,
AxisInt,
Expand Down Expand Up @@ -137,21 +141,19 @@ def view(self, dtype: Dtype | None = None) -> ArrayLike:
cls = dtype.construct_array_type() # type: ignore[assignment]
dt64_values = arr.view(f"M8[{dtype.unit}]")
return cls(dt64_values, dtype=dtype)
elif dtype == "M8[ns]":
elif lib.is_np_dtype(dtype, "M") and is_supported_unit(
get_unit_from_dtype(dtype)
):
from pandas.core.arrays import DatetimeArray

# error: Argument 1 to "view" of "ndarray" has incompatible type
# "ExtensionDtype | dtype[Any]"; expected "dtype[Any] | type[Any]
# | _SupportsDType[dtype[Any]]"
dt64_values = arr.view(dtype) # type: ignore[arg-type]
dt64_values = arr.view(dtype)
return DatetimeArray(dt64_values, dtype=dtype)
elif dtype == "m8[ns]":
elif lib.is_np_dtype(dtype, "m") and is_supported_unit(
get_unit_from_dtype(dtype)
):
from pandas.core.arrays import TimedeltaArray

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

# error: Argument "dtype" to "view" of "_ArrayOrScalarCommon" has incompatible
Expand Down
17 changes: 7 additions & 10 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,17 +999,14 @@ def view(self, cls=None):
dtype = pandas_dtype(cls)

if needs_i8_conversion(dtype):
if dtype.kind == "m" and dtype != "m8[ns]":
# e.g. m8[s]
return self._data.view(cls)

idx_cls = self._dtype_to_subclass(dtype)
# NB: we only get here for subclasses that override
# _data_cls such that it is a type and not a tuple
# of types.
arr_cls = idx_cls._data_cls
arr = arr_cls(self._data.view("i8"), dtype=dtype)
return idx_cls._simple_new(arr, name=self.name, refs=self._references)
arr = self.array.view(dtype)
if isinstance(arr, ExtensionArray):
# here we exclude non-supported dt64/td64 dtypes
return idx_cls._simple_new(
arr, name=self.name, refs=self._references
)
return arr

result = self._data.view(cls)
else:
Expand Down
16 changes: 16 additions & 0 deletions pandas/tests/indexes/numeric/test_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,19 @@ def test_map_dtype_inference_overflows():
# TODO: we could plausibly try to infer down to int16 here
expected = Index([1000, 2000, 3000], dtype=np.int64)
tm.assert_index_equal(result, expected)


def test_view_to_datetimelike():
# GH#55710
idx = Index([1, 2, 3])
res = idx.view("m8[s]")
expected = pd.TimedeltaIndex(idx.values.view("m8[s]"))
tm.assert_index_equal(res, expected)

res2 = idx.view("m8[D]")
expected2 = idx.values.view("m8[D]")
tm.assert_numpy_array_equal(res2, expected2)

res3 = idx.view("M8[h]")
expected3 = idx.values.view("M8[h]")
tm.assert_numpy_array_equal(res3, expected3)

0 comments on commit 0a7477b

Please sign in to comment.