遍历scipy.sparse向量(或矩阵)
我想知道最好的方法是用scipy.sparse迭代稀疏矩阵的非零条目。例如,如果我执行以下操作:
from scipy.sparse import lil_matrix
x = lil_matrix( (20,1) )
x[13,0] = 1
x[15,0] = 2
c = 0
for i in x:
print c, i
c = c+1
输出是
0
1
2
3
4
5
6
7
8
9
10
11
12
13 (0, 0) 1.0
14
15 (0, 0) 2.0
16
17
18
19
因此看来迭代器正在接触每个元素,而不仅仅是非零条目。我看过API
http://docs.scipy.org/doc/scipy/reference/generation/scipy.sparse.lil_matrix.html
并搜索了一下,但是我似乎找不到有效的解决方案。
-
编辑:bbtrb的方法(使用coo_matrix)是远远超过我原来的建议更快,使用非零。Sven
Marnach的使用建议itertools.izip
也提高了速度。目前最快的是using_tocoo_izip
:import scipy.sparse import random import itertools def using_nonzero(x): rows,cols = x.nonzero() for row,col in zip(rows,cols): ((row,col), x[row,col]) def using_coo(x): cx = scipy.sparse.coo_matrix(x) for i,j,v in zip(cx.row, cx.col, cx.data): (i,j,v) def using_tocoo(x): cx = x.tocoo() for i,j,v in zip(cx.row, cx.col, cx.data): (i,j,v) def using_tocoo_izip(x): cx = x.tocoo() for i,j,v in itertools.izip(cx.row, cx.col, cx.data): (i,j,v) N=200 x = scipy.sparse.lil_matrix( (N,N) ) for _ in xrange(N): x[random.randint(0,N-1),random.randint(0,N-1)]=random.randint(1,100)
产生以下
timeit
结果:% python -mtimeit -s'import test' 'test.using_tocoo_izip(test.x)' 1000 loops, best of 3: 670 usec per loop % python -mtimeit -s'import test' 'test.using_tocoo(test.x)' 1000 loops, best of 3: 706 usec per loop % python -mtimeit -s'import test' 'test.using_coo(test.x)' 1000 loops, best of 3: 802 usec per loop % python -mtimeit -s'import test' 'test.using_nonzero(test.x)' 100 loops, best of 3: 5.25 msec per loop