我要执行两个一维数组x和y的“稀疏外部乘积”,但要遵循稀疏的“模板矩阵”T。例如,我想计算类似的内容
x= np.array([1,2,3,4])
y= np.array([5,6,7])
T=np.array([[1,0,0],[0,0,1],[1,1,0],[0,1,0]])
np.multiply(T,np.outer(x,y))
产生
array([[ 5, 0, 0],
[ 0, 0, 14],
[15, 18, 0],
[ 0, 24, 0]])
面临的挑战是要加快这一步。幼稚的代码的基本计算问题是它在外部乘积中执行许多不必要的乘法。在模板非零的情况下,只应执行一次乘法。
我尝试使用SciPy稀疏方法,例如:
T_lil=lil_matrix(T)
T_csr=T_lil.tocsr()
diags(x).dot(T_csr.dot(diags(y)))
从理论上讲,这是通过先将T应用于y,然后将x应用于结果来避免不必要的乘法。对于大尺寸,它具有速度优势,但是对于小尺寸,它是如此之慢,以至于我知道它不是最佳的。
我也尝试过类似的事情
x_column=np.array([x]).T
(T_csr.multiply(x_column)).multiply(y)
(在应用.toarray()之后)给出相同的答案,但是这很笨拙,而且也不是最优的。
我认为将x和y转换为稀疏编码不会有帮助,因为它们在我的应用程序中通常不是稀疏的。
有人可以帮忙吗?对于我的应用程序,T可能有10 ^ 4行和10 ^ 5列。我根本不介意深入研究csr(或csc或coo或dok)编码的精髓,但是我希望有人知道比我想象的更好的答案。
答案 0 :(得分:1)
您可以使用COO格式的T
矩阵来完成一些简单的操作。使用高级索引将T.data
和x
和y
的正确元素相乘:
result = coo_matrix((T.data * x[T.row] * y[T.col], (T.row.copy(), T.col.copy())),
shape=T.shape)
copy
调用避免了在某些情况下修改T
或result
中的一个可能影响另一个的情况。如果确定不会修改矩阵,则可以将其删除。
另外,请注意,此result
可能具有明确的零,尤其是在x
或y
具有任何零的情况下。