diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 76aa426cc1cee..b271cc92f7640 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -1154,7 +1154,7 @@ Sparse ^^^^^^ - Bug in :meth:`Series.astype` when converting a ``SparseDtype`` with ``datetime64[ns]`` subtype to ``int64`` dtype raising, inconsistent with the non-sparse behavior (:issue:`49631`,:issue:`50087`) - Bug in :meth:`Series.astype` when converting a from ``datetime64[ns]`` to ``Sparse[datetime64[ns]]`` incorrectly raising (:issue:`50082`) -- +- Bug in :meth:`Series.sparse.to_coo` raising ``SystemError`` when :class:`MultiIndex` contains a ``ExtensionArray`` (:issue:`50996`) ExtensionArray ^^^^^^^^^^^^^^ diff --git a/pandas/core/arrays/sparse/scipy_sparse.py b/pandas/core/arrays/sparse/scipy_sparse.py index 8e3ba57cbaba4..723449dfcd4a3 100644 --- a/pandas/core/arrays/sparse/scipy_sparse.py +++ b/pandas/core/arrays/sparse/scipy_sparse.py @@ -73,7 +73,7 @@ def _levels_to_axis( else: levels_values = lib.fast_zip( - [ss.index.get_level_values(lvl).values for lvl in levels] + [ss.index.get_level_values(lvl).to_numpy() for lvl in levels] ) codes, ax_labels = factorize(levels_values, sort=sort_labels) ax_coords = codes[valid_ilocs] diff --git a/pandas/tests/arrays/sparse/test_accessor.py b/pandas/tests/arrays/sparse/test_accessor.py index 7d6a9e18a26c6..3edece71d1d2a 100644 --- a/pandas/tests/arrays/sparse/test_accessor.py +++ b/pandas/tests/arrays/sparse/test_accessor.py @@ -183,6 +183,25 @@ def test_to_coo_nonzero_fill_val_raises(self, fill_value): with pytest.raises(ValueError, match="fill value must be 0"): df.sparse.to_coo() + @td.skip_if_no_scipy + def test_to_coo_midx_categorical(self): + # GH#50996 + import scipy.sparse + + midx = pd.MultiIndex.from_arrays( + [ + pd.CategoricalIndex(list("ab"), name="x"), + pd.CategoricalIndex([0, 1], name="y"), + ] + ) + + ser = pd.Series(1, index=midx, dtype="Sparse[int]") + result = ser.sparse.to_coo(row_levels=["x"], column_levels=["y"])[0] + expected = scipy.sparse.coo_matrix( + (np.array([1, 1]), (np.array([0, 1]), np.array([0, 1]))), shape=(2, 2) + ) + assert (result != expected).nnz == 0 + def test_to_dense(self): df = pd.DataFrame( {