11

是否有一种简单/内置的方法来获得两个(或理想情况下更多)稀疏矩阵的元素最大值?即np.maximum的稀疏等价物。

4

6 回答 6

5

这成功了:

def maximum (A, B):
    BisBigger = A-B
    BisBigger.data = np.where(BisBigger.data < 0, 1, 0)
    return A - A.multiply(BisBigger) + B.multiply(BisBigger)
于 2013-10-11T12:32:25.130 回答
2

不,在scipy.sparse. 简单的解决方案是

np.maximum(X.A, Y.A)

但是当矩阵的维度很大时,这显然会占用大量内存,并且可能会使您的机器崩溃。一种内存高效(但绝不是快速)的解决方案是

# convert to COO, if necessary
X = X.tocoo()
Y = Y.tocoo()

Xdict = dict(((i, j), v) for i, j, v in zip(X.row, X.col, X.data))
Ydict = dict(((i, j), v) for i, j, v in zip(Y.row, Y.col, Y.data))

keys = list(set(Xdict.iterkeys()).union(Ydict.iterkeys()))

XmaxY = [max(Xdict.get((i, j), 0), Ydict.get((i, j), 0)) for i, j in keys]
XmaxY = coo_matrix((XmaxY, zip(*keys)))

请注意,这使用纯 Python 而不是矢量化的习语。您可以尝试通过矢量化部分运行时间来减少一些运行时间。

于 2013-10-11T11:15:24.037 回答
1

这是另一个节省内存的解决方案,应该比 larsmans 快一点。它基于使用Jaime 在此处的出色答案中的代码找到两个数组中非零元素的唯一索引集。

import numpy as np
from scipy import sparse

def sparsemax(X, Y):

    # the indices of all non-zero elements in both arrays
    idx = np.hstack((X.nonzero(), Y.nonzero()))

    # find the set of unique non-zero indices
    idx = tuple(unique_rows(idx.T).T)

    # take the element-wise max over only these indices
    X[idx] = np.maximum(X[idx].A, Y[idx].A)

    return X

def unique_rows(a):
    void_type = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
    b = np.ascontiguousarray(a).view(void_type)
    idx = np.unique(b, return_index=True)[1]
    return a[idx]

测试:

def setup(n=1000, fmt='csr'):
    return sparse.rand(n, n, format=fmt), sparse.rand(n, n, format=fmt)

X, Y = setup()
Z = sparsemax(X, Y)
print np.all(Z.A == np.maximum(X.A, Y.A))
# True

%%timeit X, Y = setup()
sparsemax(X, Y)
# 100 loops, best of 3: 4.92 ms per loop
于 2013-10-12T00:07:04.730 回答
1

最新scipy版本 (13.0) 为稀疏矩阵定义了逐元素布尔值。所以:

BisBigger = B>A
A - A.multiply(BisBigger) + B.multiply(BisBigger)

np.maximum(还)不起作用,因为它使用np.where,仍在尝试获取truth value of an array.

奇怪地B>A返回一个布尔 dtype,B>=A而是 float64。

于 2013-10-12T03:46:01.773 回答
1

这是一个函数,它返回一个稀疏矩阵,该矩阵是两个稀疏矩阵的元素最大值。它通过hpaulj实现了答案:

def sparse_max(A, B):
    """
    Return the element-wise maximum of sparse matrices `A` and `B`.
    """
    AgtB = (A > B).astype(int)
    M = AgtB.multiply(A - B) + B
    return M

测试:

A = sparse.csr_matrix(np.random.randint(-9,10, 25).reshape((5,5))) 
B = sparse.csr_matrix(np.random.randint(-9,10, 25).reshape((5,5)))

M = sparse_max(A, B)
M2 = sparse_max(B, A)

# Test symmetry:
print((M.A == M2.A).all())
# Test that M is larger or equal to A and B, element-wise:
print((M.A >= A.A).all())
print((M.A >= B.A).all())
于 2020-07-23T16:21:06.547 回答
0
from scipy import sparse
from numpy import array
I = array([0,3,1,0])
J = array([0,3,1,2])
V = array([4,5,7,9])
A = sparse.coo_matrix((V,(I,J)),shape=(4,4))

A.data.max()
9

如果您还没有,您应该尝试ipython,您可以节省自己的时间来制作您的备用矩阵,A然后只需键入A.然后选项卡,这将打印您可以调用的方法列表A。从这里你会看到A.data给你非零条目作为一个数组,因此你只想要这个的最大值。

于 2013-10-11T06:30:22.443 回答