Scipy equivalent of numpy where for sparse matrices

scipy sparse matrix multiplication
scipy sparse multiply matrix
sparse matrix to numpy array
csr matrix multiplication
scipy sparse matrix access element
scipy sparse matrix indexing
scipy sparse matrix column names
scipy coo matrix

I am looking for an equivalent of numpy.where to be used with the sparse representations that scipy offers (scipy.sparse). Is there anything that lets you deal with those matrices as if you where using an if-then-else statement?

UPDATE To be more specific: I need where as an if-then-else vectorialized function, i.e. in tasks like, for each value that equals K in matrix A, put a corresponding value in matrix B, else C. You could use something like find to retrieve the indexes of those entries that satisfy the logical condition, then negate them to find all the remaining ones, but for sparse matrices, isn't there a more compact way?


Here's a function that duplicates np.where, when cond, x, and y are matching sized sparse matrices.

def where1(cond, x):
    # elements of x where cond
    row, col, data = sparse.find(cond) # effectively the coo format
    data = np.ones(data.shape, dtype=x.dtype)
    zs = sparse.coo_matrix((data, (row, col)), shape=cond.shape)
    xx = x.tocsr()[row, col][0]
    zs.data[:] = xx
    zs = zs.tocsr()
    zs.eliminate_zeros()
    return zs

def where2(cond, y):
    # elements of y where not cond
    row, col, data = sparse.find(cond)
    zs = y.copy().tolil() # faster for this than the csr format
    zs[row, col] = 0
    zs = zs.tocsr()
    zs.eliminate_zeros()
    return zs

def where(cond, x, y):
    # like np.where but with sparse matrices
    ws1 = where1(cond, x)
    # ws2 = where1(cond==0, y) # cond==0 is likely to produce a SparseEfficiencyWarning
    ws2 = where2(cond, y)
    ws = ws1 + ws2
    # test against np.where
    w = np.where(cond.A, x.A, y.A)
    assert np.allclose(ws.A, w)
    return ws

m,n, d = 100,90, 0.5
cs = sparse.rand(m,n,d)
xs = sparse.rand(m,n,d)
ys = sparse.rand(m,n,d)
print where(cs, xs, ys).A

Even after figuring out how to code where1, it took further thought to figure out a way to apply the not side of the problem without generating a warning. Its not as general or fast as the dense where, but it illustrates the complexity that's involved in building sparse matrices this way.

It's worth noting that

np.where(cond) == np.nonzero(cond) # see doc

xs.nonzero() == (xs.row, xs.col) # for coo format
sparse.find(xs) == (row, col, data)

np.where with x and y is equivalent to:

[xv if c else yv for (c,xv,yv) in zip(condition,x,y)]  # see doc

The C code probably implements this with an nditer, which is functionally like zip, stepping through all the elements of the inputs and output. If the output is anywhere close to dense (e.g. y=2), then the np.where will be faster than this sparse substitute.

scipy.sparse.find — SciPy v1.5.2 Reference Guide, Matrix whose nonzero elements are desired. Returns. (I,J,V)tuple of arrays. I,J, and V contain the row� I am trying to use numpy.where with csr_matrix, which dose not work. I am asking is there some built in function equivalent to numpy.where for sparse matrix. Here is an example of what I would like to do without using Forloop or .todense()


You could use scipy.sparse.find (http://docs.scipy.org/doc/scipy-0.9.0/reference/generated/scipy.sparse.find.html). This function returns the non-negative values of a sparse matrix. For a certain condition you could use i.e.:

 import scipy.sparse as sp
 A = sp.csr_matrix([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
 B = A > 2 #the condition
 indexes = sp.find(B)

Sparse matrices (scipy.sparse), A sparse matrix in COOrdinate format. csc_matrix (arg1[, shape, dtype, copy]). Compressed Sparse Column matrix. To do a vector product between a sparse matrix and a vector simply use the matrix dot method, as described in its docstring: >>> import numpy as np >>> from scipy.sparse import csr_matrix >>> A = csr_matrix ([[ 1 , 2 , 0 ], [ 0 , 0 , 3 ], [ 4 , 0 , 5 ]]) >>> v = np . array ([ 1 , 0 , - 1 ]) >>> A . dot ( v ) array([ 1, -3, -1], dtype=int64)


Here's my replacement of np.where for sparse matrices using find:

def where(mask, val, arr):
    """ Sparse `where` """
    out = arr.copy()
    rows, cols, _ = find(mask)
    for r, c in zip(rows, cols):
        out[r, c] = val
    return out

scipy.sparse.csr_matrix - Numpy and Scipy Documentation, with a dense matrix or rank-2 ndarray D. csr_matrix(S). with another sparse matrix S (equivalent to S.tocsr()). csr_matrix((M, N), [dtype]). to construct an empty � For SciPy sparse matrix, one can use todense () or toarray () to transform to NumPy matrix or array. What are the functions to do the inverse? I searched, but got no idea what keywords should be the right hit. python numpy scipy sparse-matrix


scipy.sparse.csc_matrix - Numpy and Scipy Documentation, with a dense matrix or rank-2 ndarray D. csc_matrix(S). with another sparse matrix S (equivalent to S.tocsc()). csc_matrix((M, N), [dtype]). to construct an empty� Input sparse matrix. ord {non-zero int, inf, -inf, ‘fro’}, optional. Order of the norm (see table under Notes). inf means numpy’s inf object. axis {int, 2-tuple of ints, None}, optional. If axis is an integer, it specifies the axis of x along which to compute the vector norms. If axis is a 2-tuple, it specifies the axes that hold 2-D


scipy.sparse.lil_matrix — SciPy v1.5.2 Reference Guide, with a dense matrix or rank-2 ndarray D. lil_matrix(S). with another sparse matrix S (equivalent to S.tolil()). lil_matrix((M, N), [dtype]). to construct an empty matrix� A ndarray, sparse matrix or LinearOperator. An array, sparse matrix, or LinearOperator representing the operation A * x, where A is a real or complex square matrix. k int, optional. The number of eigenvalues and eigenvectors desired. k must be smaller than N-1. It is not possible to compute all eigenvectors of a matrix. M ndarray, sparse matrix


scipy.sparse.coo_matrix — SciPy v1.5.2 Reference Guide, with another sparse matrix S (equivalent to S.tocoo()) Constructing a matrix using ijv format >>> row = np.array([0, 3, 1, 0]) >>> col = np.array([0, 3, 1,� scipy.sparse.csr_matrix¶ class scipy.sparse.csr_matrix (arg1, shape = None, dtype = None, copy = False) [source] ¶ Compressed Sparse Row matrix. This can be instantiated in several ways: csr_matrix(D) with a dense matrix or rank-2 ndarray D. csr_matrix(S) with another sparse matrix S (equivalent to S.tocsr()) csr_matrix((M, N), [dtype])