Python 向量与csr_矩阵的左乘法
我有一个大小为50*10000的csr格式稀疏矩阵Python 向量与csr_矩阵的左乘法,python,scipy,sparse-matrix,Python,Scipy,Sparse Matrix,我有一个大小为50*10000的csr格式稀疏矩阵a,和一个大小为50的np.arrayv,我想计算乘积v.dot(a)。我如何有效地做到这一点 当然,运行v.dot(A)不是一个好主意,因为scipy.sparse不支持np操作。不幸的是,据我所知,scipy.sparse没有矩阵与向量左乘的函数 我尝试过以下方法,但所有这些方法似乎都花费了大量时间: 转换A并使用标准的.dot 我转置A,然后使用.dot方法。这将A.T与v相乘作为列向量 ``` >>> A = spars
a
,和一个大小为50的np.arrayv
,我想计算乘积v.dot(a)
。我如何有效地做到这一点
当然,运行v.dot(A)
不是一个好主意,因为scipy.sparse不支持np操作。不幸的是,据我所知,scipy.sparse没有矩阵与向量左乘的函数
我尝试过以下方法,但所有这些方法似乎都花费了大量时间:
.dot
.dot
方法。这将A.T
与v
相乘作为列向量
```
>>> A = sparse.csr_matrix([[1, 2, 0, 0],
... [0, 0, 3, 4]])
>>> v = np.array([1, 1])
>>> A.T.dot(v)
array([1, 2, 3, 4], dtype=int32)
```
csr\u matrix.multiply()
方法,它执行逐点乘法。我将对这些行求和
>>> vt = v[np.newaxis].T
>>> A.multiply(vt).sum(axis=0)
matrix([[1, 2, 3, 4]], dtype=int32)
.dot
方法方法1是目前最快的,但是
.T
方法仍然非常耗时。有没有更好的方法在稀疏矩阵上执行左乘法?该@运算符也适用于scipy稀疏矩阵,与您的方法进行简短而粗略的性能比较表明,@运算符的性能与您的方法1类似
In [746]: A = sparse.csr_matrix([[1, 2, 0, 0],
...: ... [0, 0, 3, 4]])
In [747]: A
Out[747]:
<2x4 sparse matrix of type '<class 'numpy.longlong'>'
with 4 stored elements in Compressed Sparse Row format>
In [748]: print(A)
(0, 0) 1
(0, 1) 2
(1, 2) 3
(1, 3) 4
In [749]: v = np.array([1, 1])
实际上,与制作原始稀疏矩阵所需的时间相比,该时间相当不错:
In [759]: timeit A = sparse.csr_matrix([[1, 2, 0, 0], [0, 0, 3, 4]])
349 µs ± 356 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [799]: Ab = sparse.random(1000,1000,.001,'csr')
In [800]: timeit Ab.sum(axis=0)
269 µs ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [801]: timeit Ab.T*np.ones(1000)
118 µs ± 216 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
稀疏优化用于大型非常稀疏矩阵的矩阵乘法。使用密集阵列(只要它们适合内存),大多数其他操作都会更快
稀疏矩阵的默认乘法是矩阵
In [752]: A.T*v
Out[752]: array([1, 2, 3, 4], dtype=int64)
In [753]: A.T.dot(v)
Out[753]: array([1, 2, 3, 4], dtype=int64)
In [754]: A.T@(v)
Out[754]: array([1, 2, 3, 4], dtype=int64)
@
,\uuuuuuuuuuuuuuuuuuuuuuuuuuu
委托给\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu
。稀疏dot
也可以
*
和点
时间相同,@
稍微慢一点。
In[758]:timeit A.T*(v)每个回路95.6µs±424 ns(7次运行的平均值±标准偏差,每个10000个回路) 从时间中删除转置:
In [760]: %%timeit A1=A.T
...: A1*v
7.77 µs ± 22.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
第二种方法使用稀疏元素乘法:
In [774]: A.multiply(v[:,None]).sum(axis=0)
Out[774]: matrix([[1, 2, 3, 4]], dtype=int64)
这不如矩阵乘法有效
In [775]: A.multiply(v[:,None])
Out[775]:
<2x4 sparse matrix of type '<class 'numpy.longlong'>'
with 4 stored elements in COOrdinate format>
In [776]: timeit A.multiply(v[:,None])
147 µs ± 1.14 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
应谨慎看待所有这些时间安排<代码>A很小,不是很稀疏。将此行和与更大的稀疏矩阵进行比较:
In [759]: timeit A = sparse.csr_matrix([[1, 2, 0, 0], [0, 0, 3, 4]])
349 µs ± 356 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [799]: Ab = sparse.random(1000,1000,.001,'csr')
In [800]: timeit Ab.sum(axis=0)
269 µs ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [801]: timeit Ab.T*np.ones(1000)
118 µs ± 216 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
我刚刚看到我写的方法3是最有效的!方法1是最有效的。我会编辑的。但无论如何都很棒!
In [799]: Ab = sparse.random(1000,1000,.001,'csr')
In [800]: timeit Ab.sum(axis=0)
269 µs ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [801]: timeit Ab.T*np.ones(1000)
118 µs ± 216 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)