Skip to content

Commit ac14e3c

Browse files
committed
Rework
1 parent 438d084 commit ac14e3c

File tree

5 files changed

+43
-13
lines changed

5 files changed

+43
-13
lines changed

doc/source/whatsnew/v2.2.2.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Fixed regressions
1616
- :meth:`DataFrame.__dataframe__` was producing incorrect data buffers when the a column's type was a pandas nullable on with missing values (:issue:`56702`)
1717
- :meth:`DataFrame.__dataframe__` was producing incorrect data buffers when the a column's type was a pyarrow nullable on with missing values (:issue:`57664`)
1818
- Avoid issuing a spurious ``DeprecationWarning`` when a custom :class:`DataFrame` or :class:`Series` subclass method is called (:issue:`57553`)
19+
- Fixed regression in :meth:`Index.map` that would not change the dtype when the provided mapping would change data from tz-aware to tz-agnostic or tz-agnostic to tz-aware (:issue:`57192`)
1920
- Fixed regression in precision of :func:`to_datetime` with string and ``unit`` input (:issue:`57051`)
2021

2122
.. ---------------------------------------------------------------------------

pandas/_libs/lib.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def is_timedelta_or_timedelta64_array(
5454
values: np.ndarray, skipna: bool = True
5555
) -> bool: ...
5656
def is_datetime_with_singletz_array(values: np.ndarray) -> bool: ...
57+
def is_datetime_naive_array(values: np.ndarray) -> bool: ...
5758
def is_time_array(values: np.ndarray, skipna: bool = ...): ...
5859
def is_date_array(values: np.ndarray, skipna: bool = ...): ...
5960
def is_datetime_array(values: np.ndarray, skipna: bool = ...): ...

pandas/_libs/lib.pyx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,30 @@ def is_datetime_with_singletz_array(values: ndarray) -> bool:
20682068
return True
20692069

20702070

2071+
def is_datetime_naive_array(values: ndarray) -> bool:
2072+
"""
2073+
Check values have are datetime naive.
2074+
Doesn't check values are datetime-like types.
2075+
"""
2076+
cdef:
2077+
Py_ssize_t j, n = len(values)
2078+
object tz
2079+
2080+
if n == 0:
2081+
return False
2082+
2083+
for j in range(n):
2084+
# Compare val's timezone with the reference timezone
2085+
# NaT can coexist with tz-aware datetimes, so skip if encountered
2086+
# val = values[j]
2087+
# if val is not NaT and val is not None and not util.is_nan(val):
2088+
tz = getattr(values[j], "tzinfo", None)
2089+
if tz is not None:
2090+
return False
2091+
2092+
return True
2093+
2094+
20712095
@cython.internal
20722096
cdef class TimedeltaValidator(TemporalValidator):
20732097
cdef bint is_value_typed(self, object value) except -1:

pandas/core/arrays/datetimes.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,15 @@ def _scalar_type(self) -> type[Timestamp]:
290290

291291
@classmethod
292292
def _from_scalars(cls, scalars, *, dtype: DtypeObj) -> Self:
293-
if lib.infer_dtype(scalars, skipna=True) not in ["datetime", "datetime64"]:
294-
# TODO: require any NAs be valid-for-DTA
295-
# TODO: if dtype is passed, check for tzawareness compat?
293+
# TODO: require any NAs be valid-for-DTA
294+
# TODO: if dtype is passed, check for tzawareness compat?
295+
if not lib.is_datetime64_array(scalars):
296+
raise ValueError
297+
elif isinstance(
298+
dtype, DatetimeTZDtype
299+
) and not lib.is_datetime_with_singletz_array(scalars):
300+
raise ValueError
301+
elif isinstance(dtype, np.dtype) and not lib.is_datetime_naive_array(scalars):
296302
raise ValueError
297303
return cls._from_sequence(scalars, dtype=dtype)
298304

pandas/core/indexes/base.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6103,16 +6103,14 @@ def map(self, mapper, na_action: Literal["ignore"] | None = None):
61036103
# empty
61046104
dtype = self.dtype
61056105

6106-
if self.inferred_type != "datetime64":
6107-
# e.g. if we are floating and new_values is all ints, then we
6108-
# don't want to cast back to floating. But if we are UInt64
6109-
# and new_values is all ints, we want to try.
6110-
# GH#57192 - we skip datetime64 because inference from values is reliable
6111-
same_dtype = lib.infer_dtype(new_values, skipna=False) == self.inferred_type
6112-
if same_dtype:
6113-
new_values = maybe_cast_pointwise_result(
6114-
new_values, self.dtype, same_dtype=same_dtype
6115-
)
6106+
# e.g. if we are floating and new_values is all ints, then we
6107+
# don't want to cast back to floating. But if we are UInt64
6108+
# and new_values is all ints, we want to try.
6109+
same_dtype = lib.infer_dtype(new_values, skipna=False) == self.inferred_type
6110+
if same_dtype:
6111+
new_values = maybe_cast_pointwise_result(
6112+
new_values, self.dtype, same_dtype=same_dtype
6113+
)
61166114

61176115
return Index._with_infer(new_values, dtype=dtype, copy=False, name=self.name)
61186116

0 commit comments

Comments
 (0)