Eric Leschinski
Eric Leschinski

Reputation: 153822

Python empty csr_matrix throws ValueError: cannot infer dimensions from zero sized index arrays

Here's the python SSCCE:

import scipy.sparse
data = []
row = []
col = []
csr = scipy.sparse.csr_matrix((data, (row, col)))  #error happens here
print(type(csr))
print(csr)

I'm running it with python2.7 I get an error:

raise ValueError('cannot infer dimensions from zero sized index arrays')
ValueError: cannot infer dimensions from zero sized index arrays

It works correctly when I feed them values like this:

csr = scipy.sparse.csr_matrix(([10,20,30], ([0,0,0],[0,1,2])))

or like this:

csr = scipy.sparse.csr_matrix(([10,20], ([0,0],[0,1])))
csr = scipy.sparse.csr_matrix(([10], ([0],[0])))

I read the documentation at: http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.html and

http://docs.scipy.org/doc/scipy/reference/sparse.html#usage-information

but that doesn't seem to explain why I can't make a csr matrix with zero items in it.

What's going on with this error? I guess scipy.sparse.csr.csr_matrix types must have at least one value in them on instantiation? That seems like a silly restriction.

Upvotes: 1

Views: 4184

Answers (2)

hpaulj
hpaulj

Reputation: 231325

You can make an empty sparse matrix - from an empty dense one or by giving the shape parameter:

In [477]: from scipy import sparse
In [478]: sparse.csr_matrix([])
Out[478]: 
<1x0 sparse matrix of type '<class 'numpy.float64'>'
    with 0 stored elements in Compressed Sparse Row format>
In [479]: sparse.csr_matrix(([],([],[])),shape=(0,0))
Out[479]: 
<0x0 sparse matrix of type '<class 'numpy.float64'>'
    with 0 stored elements in Compressed Sparse Row format>

You can even create a large empty one with shape:

In [480]: sparse.csr_matrix(([],([],[])),shape=(1000,1000))
Out[480]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
    with 0 stored elements in Compressed Sparse Row format>
In [481]: M=_
In [482]: M[34,334]=1000
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  SparseEfficiencyWarning)

But given the inefficiency of inserting values or concatenating a new matrix, I don't see why you'd want to make such a creature.

The relevant code from sparse.coo_matrix when the first argument is a tuple:

           try:
                obj, (row, col) = arg1
            except (TypeError, ValueError):
                raise TypeError('invalid input format')

            if shape is None:
                if len(row) == 0 or len(col) == 0:
                    raise ValueError('cannot infer dimensions from zero '
                                     'sized index arrays')
                M = np.max(row) + 1
                N = np.max(col) + 1
                self.shape = (M, N)

Upvotes: 0

Warren Weckesser
Warren Weckesser

Reputation: 114781

Scipy sparse matrices have a definite shape, e.g. (m, n) where m is the number of rows and n is the number of columns. When you write, for example, csr_matrix(([1, 2], ([0, 3], [1, 4]))), csr_matrix infers the shape from the maximum values of the row and column indices. But when you write csr_matrix(([], ([], []))), the function has no way of knowing what the shape of the matrix should be (and I guess it won't create a matrix with shape (0, 0) by default).

One way to handle that is to give an explicit shape:

In [241]: csr_matrix(([], ([], [])), shape=(3, 3))
Out[241]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 0 stored elements in Compressed Sparse Row format>

Upvotes: 2

Related Questions