元素最大的两个稀疏矩阵

时间:2013-10-11 06:09:24

标签: python numpy scipy

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

6 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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而不是矢量化的习语。您可以通过矢量化部分来尝试削减一些运行时间。

答案 2 :(得分:1)

这是另一种内存效率高的解决方案,应该比larsmans快一点。它基于使用Jaime's excellent answer here中的代码为两个数组中的非零元素查找唯一索引集。

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

答案 3 :(得分:1)

最新的scipy(13.0)为稀疏matricies定义了元素方面的布尔值。所以:

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。

答案 4 :(得分: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())

答案 5 :(得分: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为数组提供非零条目,因此您只需要最大值。