所以,我正在使用稀疏的numpy数组进行一些Kmeans分类-很多零。我发现我会使用scipy的“稀疏”包来减少存储开销,但是我对如何创建数组而不是矩阵有些困惑。
我已经完成了有关如何创建稀疏矩阵的教程:
http://www.scipy.org/SciPy_Tutorial#head-c60163f2fd2bab79edd94be43682414f18b90df7
为了模拟一个数组,我只创建了一个1xN的矩阵,但是正如您可能猜到的,Asp.dot(Bsp)不能完全起作用,因为您不能将两个1xN的矩阵相乘。我必须将每个数组转置为Nx1,这很la脚,因为我会在每次点积计算中都这样做。
接下来,我尝试创建一个NxN矩阵,其中第1列==第1行(这样,您可以将两个矩阵相乘,并且只将左上角作为点积),但是事实证明这效率很低。
我很乐意使用scipy的稀疏包作为numpy的array()的魔术替代品,但是到目前为止,我还不确定该怎么做。
有什么建议吗?
最佳答案
使用基于行或列的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
请注意,这最后一种方法会再次执行Numpy密集乘法。稀疏度为50%,因此实际上比
dot(x, x)
快2倍。关于python - 稀疏稀疏…数组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2540059/