我正在寻找与scipy offer(numpy.where
)的稀疏表示一起使用的等效scipy.sparse
。
是否有任何东西可以让你处理这些矩阵,就好像你在那里使用if-then-else语句一样?
更新
更具体一点:我需要where
作为if-then-else矢量化函数,即在诸如对于矩阵A中等于K的每个值的任务中,将相应的值放在矩阵B中,否则C.
您可以使用find
之类的东西来检索那些满足逻辑条件的条目的索引,然后否定它们以找到所有剩余的条目,但对于稀疏矩阵,是不是有更紧凑的方法?
答案 0 :(得分:5)
您可以使用scipy.sparse.find(http://docs.scipy.org/doc/scipy-0.9.0/reference/generated/scipy.sparse.find.html)。 此函数返回稀疏矩阵的非负值。 对于某种情况,你可以使用,即:
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)
答案 1 :(得分:2)
当np.where
,cond
和x
匹配大小稀疏的矩阵时,这是一个重复y
的函数。
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
即使在弄清楚如何编码where1
后,还需要进一步考虑找出一种方法来应用问题的not
方而不会产生警告。它不像密集where
那样通用或快速,但它说明了以这种方式构建稀疏矩阵所涉及的复杂性。
值得注意的是
np.where(cond) == np.nonzero(cond) # see doc
xs.nonzero() == (xs.row, xs.col) # for coo format
sparse.find(xs) == (row, col, data)
带有x和y的 np.where
相当于:
[xv if c else yv for (c,xv,yv) in zip(condition,x,y)] # see doc
C代码可能使用nditer
实现此功能,其功能类似于zip
,逐步执行输入和输出的所有元素。如果输出接近密集(例如y=2
),那么np.where
将比这个稀疏替代更快。
答案 2 :(得分:0)