2

Consider the following example:

import numpy as np
import scipy.sparse

A = scipy.sparse.csr_matrix((2,2))
b = A.sum(axis=0)

The matrix b now has the form

matrix([[ 0.,  0.]])

However, I'd like it to become an array like this:

array([ 0.,  0.])

This can by done by b = np.asarray(b)[0], but that does not seem very elegant, especially compared to MATLAB's b(:). Is there a more elegant way to do this?

Kurt Peek
  • 52,165
  • 91
  • 301
  • 526
  • 2
    See http://stackoverflow.com/questions/26576524/how-do-i-transform-a-scipy-sparse-matrix-to-a-numpy-matrix; in particular, note that the sparse matrix has the method `.toarray()`, the result of which you could reshape into a one-dimensional numpy array. – Warren Weckesser Jul 15 '16 at 21:40
  • MATLAB's `b(:)` - what's the size? Still 2d isnt' it? `(:)` is a bit like a `np.ravel`, except MATLAB is always 2d or higher. – hpaulj Jul 15 '16 at 22:58

2 Answers2

3

b.A1 will do the job.

In [83]: A
Out[83]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>'
    with 0 stored elements in Compressed Sparse Row format>

In [84]: A.A
Out[84]: 
array([[ 0.,  0.],
       [ 0.,  0.]])

In [85]: b=A.sum(axis=0)

In [86]: b
Out[86]: matrix([[ 0.,  0.]])

In [87]: b.A1
Out[87]: array([ 0.,  0.])

In [88]: A.A.sum(axis=0)     # another way
Out[88]: array([ 0.,  0.])

You can up vote this, or add to my top grossing answer here: Numpy matrix to array :)

A is a sparse matrix. Sparse sum is performed with a matrix product (an appropriate matrix of 1s). The result is a dense matrix.

Sparse matrix has a toarray() method, with a .A shortcut.

Dense matrix also has those, but it also has a .A1 (poorly documented - hence all my hits), which flattens as well.

The doc for A1:

Return `self` as a flattened `ndarray`.
Equivalent to ``np.asarray(x).ravel()``

In fact the code is

return self.__array__().ravel()

====================

Is MATLAB b(:) really the equivalent?

A(:) is all the elements of A, regarded as a single column.

If I read that correctly, the numpy equivalent is a transpose, or b.ravel().T. The shape would be (2,1). But in MATLAB a column matrix is the simplest form of matrix.

In [94]: b.T
Out[94]: 
matrix([[ 0.],
        [ 0.]])

(I'm an old MATLAB programmer, with Octave on my standby computer. And a copy of 3.5 on some old Windows disk. :) ).

Community
  • 1
  • 1
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • 1
    Indeed, accoding to http://docs.scipy.org/doc/numpy/reference/generated/numpy.matrix.A1.html, .A1 is equivalent to `np.asarray(x).ravel()`, and seems like the most concise option. – Kurt Peek Jul 16 '16 at 11:32
1

There are different options here. For example, you could start by converting matrix b to a 2D array. Then you'll need to transform it into a 1D array. This can be easily accomplished through NumPy's squeeze or reshape:

In [208]: np.asarray(b).squeeze()
Out[208]: array([ 0.,  0.])

In [209]: np.asarray(b).reshape((b.size,))
Out[209]: array([ 0.,  0.])

Alternatively, you could convert A to an array as suggested in @Warren Weckesser's comment. This would make it unnecessary to further convert b:

In [210]: A.toarray().sum(axis=0)
Out[210]: array([ 0.,  0.])
Tonechas
  • 13,398
  • 16
  • 46
  • 80