遍历scipy.sparse向量(或矩阵)

发布于 2021-01-29 18:44:34

我想知道最好的方法是用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

并搜索了一下,但是我似乎找不到有效的解决方案。

关注者
0
被浏览
52
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    编辑: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
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看