Scipy稀疏…数组?
所以,我正在做一些Kmeans分类,使用非常稀疏的numpy数组 – 很多很多的零。 我想我会使用scipy的'稀疏'包来减less存储开销,但我有点困惑如何创build数组,而不是matrix。
我已经通过本教程了解如何创build稀疏matrix: http : //www.scipy.org/SciPy_Tutorial#head-c60163f2fd2bab79edd94be43682414f18b90df7
为了模仿一个数组,我只是创build一个1xN的matrix,但正如你所猜测的,Asp.dot(Bsp)不能很好地工作,因为你不能乘以两个1xNmatrix。 我不得不将每个数组转换为Nx1,这是非常蹩脚的,因为我会为每个点积计算。
接下来,我尝试创build一个NxNmatrix,其中第1行==第1行(这样您可以乘以两个matrix,只需将左上angular作为点乘积),但事实certificate效率并不高。
我喜欢使用scipy的稀疏包作为numpy的数组()的魔术替代品,但是到目前为止,我并不确定该怎么做。
有什么build议?
使用基于行或列的scipy.sparse
格式: csc_matrix
和csr_matrix
。
这些使用高效的C实现(包括乘法),并且转置是一个无操作(尤其是如果调用transpose(copy=False)
),就像numpy数组一样。
编辑:通过ipython的一些时间:
import numpy, scipy.sparse n = 100000 x = (numpy.random.rand(n) * 2).astype(int).astype(float) # 50% sparse vector x_csr = scipy.sparse.csr_matrix(x) x_dok = scipy.sparse.dok_matrix(x.reshape(x_csr.shape))
现在x_csr
和x_dok
是50%稀疏:
print repr(x_csr) <1x100000 sparse matrix of type '<type 'numpy.float64'>' with 49757 stored elements in Compressed Sparse Row format>
和时间:
timeit numpy.dot(x, x) 10000 loops, best of 3: 123 us per loop timeit x_dok * x_dok.T 1 loops, best of 3: 1.73 s per loop timeit x_csr.multiply(x_csr).sum() 1000 loops, best of 3: 1.64 ms per loop timeit x_csr * x_csr.T 100 loops, best of 3: 3.62 ms per loop
所以看起来我说谎了。 转置是非常便宜的,但没有有效的C实现csr * csc(在最新的scipy 0.9.0)。 在每个调用中构造一个新的csr对象:-(
作为一个黑客(虽然scipy目前相对稳定),你可以直接在稀疏数据上做点积:
timeit numpy.dot(x_csr.data, x_csr.data) 10000 loops, best of 3: 62.9 us per loop
注意这最后一种方法再次进行了一次颠簸的密集乘法运算。 稀疏度是50%,所以它实际上比dot(x, x)
快2倍。
你可以创build一个现有的二维稀疏数组的子类
from scipy.sparse import dok_matrix class sparse1d(dok_matrix): def __init__(self, v): dok_matrix.__init__(self, (v,)) def dot(self, other): return dok_matrix.dot(self, other.transpose())[0,0] a=sparse1d((1,2,3)) b=sparse1d((4,5,6)) print a.dot(b)
我不确定它是更好还是更快,但你可以这样做,以避免使用转置:
Asp.multiply(Bsp).sum()
这只需要两个matrix的元素 – 元素乘积并且将这些乘积相加。 你可以使用任何你使用的matrix格式的子类,上面的语句就是点积。
但是,转换它们可能更容易:
Asp*Bsp.T
这似乎不是很多事情要做,但你也可以创build一个子类并修改mul ()方法。