diff --git a/doc/source/whatsnew/v1.0.4.rst b/doc/source/whatsnew/v1.0.4.rst index f1e31316f3697..132681c00d79c 100644 --- a/doc/source/whatsnew/v1.0.4.rst +++ b/doc/source/whatsnew/v1.0.4.rst @@ -28,6 +28,7 @@ Fixed regressions - Bug in :meth:`Series.groupby` would raise ``ValueError`` when grouping by :class:`PeriodIndex` level (:issue:`34010`) - Bug in :meth:`GroupBy.rolling.apply` ignores args and kwargs parameters (:issue:`33433`) - More informative error message with ``np.min`` or ``np.max`` on unordered :class:`Categorical` (:issue:`33115`) +- Fixed regression in :meth:`DataFrame.loc` and :meth:`Series.loc` throwing an error when a ``datetime64[ns, tz]`` value is provided (:issue:`32395`) - .. _whatsnew_104.bug_fixes: diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 9723343ea7af5..4ab2a25da5d20 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -402,6 +402,13 @@ def shape(self) -> Tuple[int, ...]: """ return (len(self),) + @property + def size(self) -> int: + """ + The number of elements in the array. + """ + return np.prod(self.shape) + @property def ndim(self) -> int: """ diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 5172b4a7097f3..84dd189a8a512 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -856,8 +856,10 @@ def setitem(self, indexer, value): if is_extension_array_dtype(getattr(value, "dtype", None)): # We need to be careful not to allow through strings that # can be parsed to EADtypes + is_ea_value = True arr_value = value else: + is_ea_value = False arr_value = np.array(value) # cast the values to a type that can hold nan (if necessary) @@ -894,6 +896,11 @@ def setitem(self, indexer, value): values[indexer] = value return self.make_block(Categorical(self.values, dtype=arr_value.dtype)) + elif exact_match and is_ea_value: + # GH#32395 if we're going to replace the values entirely, just + # substitute in the new array + return self.make_block(arr_value) + # if we are an exact match (ex-broadcasting), # then use the resultant dtype elif exact_match: diff --git a/pandas/tests/extension/base/interface.py b/pandas/tests/extension/base/interface.py index cdea96334be2a..95fb3d7439b56 100644 --- a/pandas/tests/extension/base/interface.py +++ b/pandas/tests/extension/base/interface.py @@ -19,6 +19,9 @@ class BaseInterfaceTests(BaseExtensionTests): def test_len(self, data): assert len(data) == 100 + def test_size(self, data): + assert data.size == 100 + def test_ndim(self, data): assert data.ndim == 1 diff --git a/pandas/tests/extension/base/setitem.py b/pandas/tests/extension/base/setitem.py index 2b46f8ec3d1c3..b3f6a608dfa3f 100644 --- a/pandas/tests/extension/base/setitem.py +++ b/pandas/tests/extension/base/setitem.py @@ -4,6 +4,7 @@ import pytest import pandas as pd +import pandas._testing as tm from pandas.core.arrays.numpy_ import PandasDtype from .base import BaseExtensionTests @@ -314,3 +315,31 @@ def test_setitem_nullable_mask(self, data): mask = pd.array([True, True, True, False, False]) arr[mask] = data[0] self.assert_extension_array_equal(expected, arr) + + def test_setitem_dataframe_column_with_index(self, data): + # https://github.com/pandas-dev/pandas/issues/32395 + df = expected = pd.DataFrame({"data": pd.Series(data)}) + result = pd.DataFrame(index=df.index) + result.loc[df.index, "data"] = df["data"] + self.assert_frame_equal(result, expected) + + def test_setitem_dataframe_column_without_index(self, data): + # https://github.com/pandas-dev/pandas/issues/32395 + df = expected = pd.DataFrame({"data": pd.Series(data)}) + result = pd.DataFrame(index=df.index) + result.loc[:, "data"] = df["data"] + self.assert_frame_equal(result, expected) + + def test_setitem_series_with_index(self, data): + # https://github.com/pandas-dev/pandas/issues/32395 + ser = expected = pd.Series(data, name="data") + result = pd.Series(index=ser.index, dtype=np.object, name="data") + result.loc[ser.index] = ser + self.assert_series_equal(result, expected) + + def test_setitem_series_without_index(self, data): + # https://github.com/pandas-dev/pandas/issues/32395 + ser = expected = pd.Series(data, name="data") + result = pd.Series(index=ser.index, dtype=np.object, name="data") + result.loc[:] = ser + self.assert_series_equal(result, expected)