首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scipy sparse...数组?

Scipy sparse...数组?
EN

Stack Overflow用户
提问于 2010-03-30 01:48:57
回答 3查看 36.1K关注 0票数 52

所以,我使用非常稀疏的numpy数组来做一些Kmeans分类--很多很多的零。我想我应该使用scipy的'sparse‘包来减少存储开销,但我对如何创建数组而不是矩阵感到有点困惑。

我已经阅读了有关如何创建稀疏矩阵的教程:http://www.scipy.org/SciPy_Tutorial#head-c60163f2fd2bab79edd94be43682414f18b90df7

为了模拟一个数组,我只创建了一个1xN矩阵,但正如您可能猜到的那样,Asp.dot(Bsp)并不能很好地工作,因为您不能将两个1xN矩阵相乘。我必须将每个数组转置为Nx1,这是相当糟糕的,因为我将在每次点积计算时都这样做。

接下来,我尝试创建一个第1列和第1行的NxN矩阵(这样您就可以将两个矩阵相乘,然后将左上角作为点积),但结果证明效率非常低。

我很想使用scipy的稀疏包作为numpy的array()的神奇替代品,但是到目前为止,我还不确定该怎么做。

有什么建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-20 06:23:11

使用基于行或列的scipy.sparse格式:csc_matrixcsr_matrix

这些在幕后使用高效的C实现(包括乘法),并且转置是一种无操作(特别是。如果调用transpose(copy=False)),就像使用numpy数组一样。

编辑:通过ipython进行一些计时

代码语言:javascript
复制
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%稀疏的:

代码语言:javascript
复制
print repr(x_csr)
<1x100000 sparse matrix of type '<type 'numpy.float64'>'
        with 49757 stored elements in Compressed Sparse Row format>

以及时间安排:

代码语言:javascript
复制
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

所以看起来我说了个谎话。转置非常便宜,但是csr * csc没有高效的C实现(在最新版本scipy 0.9.0中)。在每次调用中构造一个新的csr对象:-(

作为一种技巧(尽管scipy目前相对稳定),您可以直接在稀疏数据上进行点积:

代码语言:javascript
复制
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倍。

票数 35
EN

Stack Overflow用户

发布于 2010-03-30 02:16:22

您可以创建现有二维稀疏数组之一的子类。

代码语言:javascript
复制
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)
票数 1
EN

Stack Overflow用户

发布于 2010-03-30 02:59:31

我不确定它是否真的更好或更快,但你可以这样做,以避免使用转置:

代码语言:javascript
复制
Asp.multiply(Bsp).sum()

这只是将两个矩阵的逐个元素的乘积相加。您可以为您正在使用的任何矩阵格式创建一个子类,将上面的语句作为点积。

但是,转换它们可能更容易:

代码语言:javascript
复制
Asp*Bsp.T

这似乎并不需要做太多事情,但是您也可以创建一个子类并修改mul()方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2540059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档