diff --git a/pandas/core/arrays/numpy_.py b/pandas/core/arrays/numpy_.py index 9999a9ed411d8..8a8c4be012d99 100644 --- a/pandas/core/arrays/numpy_.py +++ b/pandas/core/arrays/numpy_.py @@ -10,6 +10,7 @@ from pandas._typing import Dtype, NpDtype, Scalar from pandas.compat.numpy import function as nv +from pandas.core.dtypes.cast import construct_1d_object_array_from_listlike from pandas.core.dtypes.dtypes import PandasDtype from pandas.core.dtypes.missing import isna @@ -86,6 +87,14 @@ def _from_sequence( dtype = dtype._dtype result = np.asarray(scalars, dtype=dtype) + if ( + result.ndim > 1 + and not hasattr(scalars, "dtype") + and (dtype is None or dtype == object) + ): + # e.g. list-of-tuples + result = construct_1d_object_array_from_listlike(scalars) + if copy and result is scalars: result = result.copy() return cls(result) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 3c27e34dcbcf6..0bdfb7ffb20d3 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -182,10 +182,17 @@ def _check_ndim(self, values, ndim): if ndim is None: ndim = values.ndim - if self._validate_ndim and values.ndim != ndim: + if self._validate_ndim: + if values.ndim != ndim: + raise ValueError( + "Wrong number of dimensions. " + f"values.ndim != ndim [{values.ndim} != {ndim}]" + ) + elif values.ndim > ndim: + # ExtensionBlock raise ValueError( "Wrong number of dimensions. " - f"values.ndim != ndim [{values.ndim} != {ndim}]" + f"values.ndim > ndim [{values.ndim} > {ndim}]" ) return ndim @@ -2178,28 +2185,6 @@ def fillna( value, limit=limit, inplace=inplace, downcast=downcast ) - def _check_ndim(self, values, ndim): - """ - ndim inference and validation. - - This is overridden by the DatetimeTZBlock to check the case of 2D - data (values.ndim == 2), which should only be allowed if ndim is - also 2. - The case of 1D array is still allowed with both ndim of 1 or 2, as - if the case for other EAs. Therefore, we are only checking - `values.ndim > ndim` instead of `values.ndim != ndim` as for - consolidated blocks. - """ - if ndim is None: - ndim = values.ndim - - if values.ndim > ndim: - raise ValueError( - "Wrong number of dimensions. " - f"values.ndim != ndim [{values.ndim} != {ndim}]" - ) - return ndim - class TimeDeltaBlock(DatetimeLikeBlockMixin): __slots__ = () diff --git a/pandas/tests/extension/test_numpy.py b/pandas/tests/extension/test_numpy.py index a5b54bc153f5d..1e876d137319d 100644 --- a/pandas/tests/extension/test_numpy.py +++ b/pandas/tests/extension/test_numpy.py @@ -186,11 +186,6 @@ def test_getitem_scalar(self, data): # AssertionError super().test_getitem_scalar(data) - @skip_nested - def test_take_series(self, data): - # ValueError: PandasArray must be 1-dimensional. - super().test_take_series(data) - class TestGroupby(BaseNumPyTests, base.BaseGroupbyTests): def test_groupby_extension_apply( @@ -219,13 +214,6 @@ def test_shift_fill_value(self, data): # np.array shape inference. Shift implementation fails. super().test_shift_fill_value(data) - @skip_nested - @pytest.mark.parametrize("box", [pd.Series, lambda x: x]) - @pytest.mark.parametrize("method", [lambda x: x.unique(), pd.unique]) - def test_unique(self, data, box, method): - # Fails creating expected - super().test_unique(data, box, method) - @skip_nested def test_fillna_copy_frame(self, data_missing): # The "scalar" for this array isn't a scalar. @@ -241,31 +229,10 @@ def test_searchsorted(self, data_for_sorting, as_series): # Test setup fails. super().test_searchsorted(data_for_sorting, as_series) - @skip_nested - def test_where_series(self, data, na_value, as_frame): - # Test setup fails. - super().test_where_series(data, na_value, as_frame) - - @pytest.mark.parametrize("repeats", [0, 1, 2, [1, 2, 3]]) - def test_repeat(self, data, repeats, as_series, use_numpy, request): - if data.dtype.numpy_dtype == object and repeats != 0: - mark = pytest.mark.xfail(reason="mask shapes mismatch") - request.node.add_marker(mark) - super().test_repeat(data, repeats, as_series, use_numpy) - @pytest.mark.xfail(reason="PandasArray.diff may fail on dtype") def test_diff(self, data, periods): return super().test_diff(data, periods) - @pytest.mark.parametrize("box", [pd.array, pd.Series, pd.DataFrame]) - def test_equals(self, data, na_value, as_series, box, request): - # Fails creating with _from_sequence - if box is pd.DataFrame and data.dtype.numpy_dtype == object: - mark = pytest.mark.xfail(reason="AssertionError in _get_same_shape_values") - request.node.add_marker(mark) - - super().test_equals(data, na_value, as_series, box) - class TestArithmetics(BaseNumPyTests, base.BaseArithmeticOpsTests): divmod_exc = None @@ -286,8 +253,11 @@ def test_divmod_series_array(self, data): def test_arith_series_with_scalar(self, data, all_arithmetic_operators): super().test_arith_series_with_scalar(data, all_arithmetic_operators) - @skip_nested - def test_arith_series_with_array(self, data, all_arithmetic_operators): + def test_arith_series_with_array(self, data, all_arithmetic_operators, request): + opname = all_arithmetic_operators + if data.dtype.numpy_dtype == object and opname not in ["__add__", "__radd__"]: + mark = pytest.mark.xfail(reason="Fails for object dtype") + request.node.add_marker(mark) super().test_arith_series_with_array(data, all_arithmetic_operators) @skip_nested @@ -322,11 +292,6 @@ def test_fillna_scalar(self, data_missing): # Non-scalar "scalar" values. super().test_fillna_scalar(data_missing) - @skip_nested - def test_fillna_series_method(self, data_missing, fillna_method): - # Non-scalar "scalar" values. - super().test_fillna_series_method(data_missing, fillna_method) - @skip_nested def test_fillna_series(self, data_missing): # Non-scalar "scalar" values. @@ -355,20 +320,6 @@ def test_merge(self, data, na_value): # Fails creating expected (key column becomes a PandasDtype because) super().test_merge(data, na_value) - @skip_nested - def test_merge_on_extension_array(self, data): - # Fails creating expected - super().test_merge_on_extension_array(data) - - @skip_nested - def test_merge_on_extension_array_duplicates(self, data): - # Fails creating expected - super().test_merge_on_extension_array_duplicates(data) - - @skip_nested - def test_transpose_frame(self, data): - super().test_transpose_frame(data) - class TestSetitem(BaseNumPyTests, base.BaseSetitemTests): @skip_nested