当我将您更改
+=为仅
=用于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)))
换句话说,由于您已经具有
rowsand
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)})一样快
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)