有没有一种简单/内置的方法可以获取两个(或更多)稀疏矩阵的逐元素最大值?即,np.maximum 的稀疏等效形式。
def maximum (A, B):
BisBigger = A-B
BisBigger.data = np.where(BisBigger.data < 0, 1, 0)
return A - A.multiply(BisBigger) + B.multiply(BisBigger)
A = coo_matrix([1,1]); B = coo_matrix([0,2]); maximum(A, B).A
输出 array([[0, 2]])
。 - Fred Foonp.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)))
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
最新的scipy
(13.0)为稀疏矩阵定义了逐元素布尔值。因此:
BisBigger = B>A
A - A.multiply(BisBigger) + B.multiply(BisBigger)
np.maximum
目前还不能使用,因为它使用了np.where
,而np.where
仍在尝试获取数组的真值。
有趣的是,B>A
返回布尔类型,而B>=A
返回float64类型。
B>=A
是什么意思。但是如果它能够做你期望的事情,并且你有两个非常稀疏的矩阵 A 和 B,那么你将得到一个非常密集的矩阵作为结果。 - Maartendef 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())
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
A
,然后输入A.
再按tab键来查看可以在A
上调用的方法列表,这样可以节省时间。从中你会发现A.data
会将非零条目作为数组返回,因此你只需要找到其中的最大值即可。.data
的最大值是负数怎么办? - Fred Foo
arcsin() Element-wise arcsin.
这样的函数。但是没有max
。您想要每个矩阵中的最大值;沿某个维度的最大值;还是跨矩阵集合的最大值? - hpaulj