Repository: pandas-dev/pandas
Pull request: Add more specific error message when user passes incorrect matrix format to from_coo
- [x] closes #26554
- [x] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Problem statement:
ERR: give better error message when providing wrong sparse matrix type in from_coo
`pd.Series.sparse.from_coo` only accepts a coo matrix format, but when giving it different matrix type, you get a not so useful error message:

```python
In [11]: import scipy.sparse

In [12]: m = scipy.sparse.csr_matrix(np.array([[0,1],[0,0]]))

In [13]: pd.Series.sparse.from_coo(m)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-13-b31c13c3a79c> in <module>
----> 1 pd.Series.sparse.from_coo(m)

~/scipy/pandas/pandas/core/arrays/sparse.py in from_coo(cls, A, dense_index)
   2015         from pandas import Series
   2016 
-> 2017         result = _coo_to_sparse_series(A, dense_index=dense_index,
   2018                                        sparse_series=False)
   2019         result = Series(result.array, index=result.index, copy=False)

~/scipy/pandas/pandas/core/sparse/scipy_sparse.py in _coo_to_sparse_series(A, dense_index)
    122     Convert a scipy.sparse.coo_matrix to a SparseSeries.
    123 
--> 124     Parameters
    125     ----------
    126     A : scipy.sparse.coo.coo_matrix

~/miniconda3/envs/dev37/lib/python3.7/site-packages/scipy/sparse/base.py in __getattr__(self, attr)
    687             return self.getnnz()
    688         else:
--> 689             raise AttributeError(attr + " not found")
    690 
    691     def transpose(self, axes=None, copy=False):

AttributeError: row not found
```

Hints from issue discussion:
Happy to take a look at this!

Commit message: - Update what's new
- Simplify scope of except Block
- comment on non-regression test

Patch to review:
diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst
index 89a9da4a73b35..739f9d36243d7 100644
--- a/doc/source/whatsnew/v0.25.0.rst
+++ b/doc/source/whatsnew/v0.25.0.rst
@@ -590,7 +590,7 @@ Sparse
 - Significant speedup in :class:`SparseArray` initialization that benefits most operations, fixing performance regression introduced in v0.20.0 (:issue:`24985`)
 - Bug in :class:`SparseFrame` constructor where passing ``None`` as the data would cause ``default_fill_value`` to be ignored (:issue:`16807`)
 - Bug in :class:`SparseDataFrame` when adding a column in which the length of values does not match length of index, ``AssertionError`` is raised instead of raising ``ValueError`` (:issue:`25484`)
-
+- Introduce a better error message in :meth:`Series.sparse.from_coo` so it returns a TypeError for inputs that are not coo matrices (:issue:`26554`)
 
 Other
 ^^^^^
diff --git a/pandas/core/sparse/scipy_sparse.py b/pandas/core/sparse/scipy_sparse.py
index 7630983421ff9..2e40e8e728370 100644
--- a/pandas/core/sparse/scipy_sparse.py
+++ b/pandas/core/sparse/scipy_sparse.py
@@ -130,10 +130,19 @@ def _coo_to_sparse_series(A, dense_index: bool = False,
     Returns
     -------
     Series or SparseSeries
+
+    Raises
+    -------
+    TypeError if A is not a coo_matrix
+
     """
     from pandas import SparseDtype
 
-    s = Series(A.data, MultiIndex.from_arrays((A.row, A.col)))
+    try:
+        s = Series(A.data, MultiIndex.from_arrays((A.row, A.col)))
+    except AttributeError:
+        raise TypeError('Expected coo_matrix. Got {} instead.'
+                        .format(type(A).__name__))
     s = s.sort_index()
     if sparse_series:
         # TODO(SparseSeries): remove this and the sparse_series keyword.
@@ -149,3 +158,4 @@ def _coo_to_sparse_series(A, dense_index: bool = False,
         ind = MultiIndex.from_product([i, j])
         s = s.reindex(ind)
     return s
+
diff --git a/pandas/tests/arrays/sparse/test_accessor.py b/pandas/tests/arrays/sparse/test_accessor.py
index 370d222c1ab4e..ac38b8694003f 100644
--- a/pandas/tests/arrays/sparse/test_accessor.py
+++ b/pandas/tests/arrays/sparse/test_accessor.py
@@ -119,3 +119,11 @@ def test_series_from_coo(self, dtype, dense_index):
             )
 
         tm.assert_series_equal(result, expected)
+
+    @td.skip_if_no_scipy
+    # non-regression test for fix to issue #26554
+    def test_series_from_coo_incorrect_format(self):
+        import scipy.sparse
+        m = scipy.sparse.csr_matrix(np.array([[0, 1], [0, 0]]))
+        with pytest.raises(TypeError):
+            pd.Series.sparse.from_coo(m)


Code review comments:
diff_hunk: @@ -130,10 +130,19 @@ def _coo_to_sparse_series(A, dense_index: bool = False,
     Returns
     -------
     Series or SparseSeries
+
+    Raises
+    -------
path: pandas/core/sparse/scipy_sparse.py
text: @user1:
this is too long (has to match the length of Raises)