Skip to content

BUG: PandasArray._from_sequence with list-of-tuples #39828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions pandas/core/arrays/numpy_.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down
33 changes: 9 additions & 24 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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__ = ()
Expand Down
59 changes: 5 additions & 54 deletions pandas/tests/extension/test_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down