为什么lil_matrix和dok_matrix与普通的dict相比这么慢?

为什么lil_matrix和dok_matrix与普通的dict相比这么慢?,第1张

为什么lil_matrix和dok_matrix与普通的dict相比这么慢?

当我将您更改

+=
为仅
=
用于2个稀疏数组时:

for row, col in zip(rows, cols):    #freqs[row,col] += 1    freqs[row,col] = 1

他们各自的时间减少了一半。消耗时间最多的是索引。使用

+=
它必须同时执行a
__getitem__
和a
__setitem__

当文档这么说

dok
并且
lil
更适合迭代构造时,它们意味着扩展其基础数据结构比其他格式更容易。

当我尝试

csr
用您的代码创建矩阵时,我得到:

/usr/lib/python2.7/dist-
packages/scipy/sparse/compressed.py:690:SparseEfficiencyWarning:更改csr_matrix的稀疏结构非常昂贵。lil_matrix效率更高。稀疏效率警告)

速度降低30倍。

因此,速度要求与诸如之类的格式有关

csr
,而不与纯Python或
numpy
结构有关。

您可能想要查看Python代码,

dok_matrix.__get_item__
dok_matrix.__set_item__
查看这样做时会发生什么
freq[r,c]


一种更快的构造方法

dok
是:

freqs = dok_matrix((1000,1000))d = dict()for row, col in zip(rows, cols):    d[(row, col)] = 1freqs.update(d)

利用a

dok
是子类字典的事实。请注意,
dok
矩阵不是字典的字典。它的键是元组之类的
(50,50)

构造相同的稀疏数组的另一种快速方法是:

freqs = sparse.coo_matrix((np.ones(1000,int),(rows,cols)))

换句话说,由于您已经具有

rows
and
cols
数组(或范围),因此请计算相应的
data
数组,然后构造稀疏数组。

但是,如果您必须在增量增长步骤之间对矩阵执行稀疏运算,那么

dok
或者
lil
可能是您的最佳选择。


开发了用于解决线性代数问题的稀疏矩阵,例如使用大型稀疏矩阵求解线性方程。几年前,我在MATLAB中使用它们来解决有限差分问题。对于这项工作,计算友好的

csr
格式是最终目标,而该
coo
格式是一种方便的初始化格式。

现在,许多SO稀疏问题都来自

scikit-learn
文本分析问题。它们还用于生物学数据库文件中。但是
(data),(row,col)
定义方法仍然效果最好。

因此,稀疏矩阵从未打算用于快速增量创建。字典和列表之类的传统Python结构对此要好得多。


dok
是利用其字典方法的更快迭代。
update
似乎和普通字典一样快。
get
大约是等效索引(
freq[row,col]
)的3倍。索引可能使用
get
,但必须有很多开销。

def fast_dok(rows, cols):    freqs = dok_matrix((1000,1000))    for row, col in zip(rows,cols):         i = freqs.get((row,col),0)         freqs.update({(row,col):i+1})    return freqs

跳过

get
,然后开始

         freqs.update({(row,col): 1)

甚至更快-比defaultdict示例的defaultdict更快,几乎与简单的字典初始化(

{(r, c):1 for r,c in zip(rows,cols)}
)一样快



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5647099.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存