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_matrixcsr_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_csrx_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 ()方法。