如何避免稀疏矩阵的循环?

时间:2013-10-13 13:41:23

标签: python numpy sparse-matrix

我在Python中遇到3个循环的问题。 此代码的目的是根据 DATA 的(x)未知值的数量计算稀疏矩阵。这里,x数是13,这意味着DATA的未重复值:(0,4,8,12,16,20,21,22,23,24,25,26,27)。然后,len(DATA)是4,表示A_sparse矩阵的行数。然后,我创建了具有形状(4,13)的稀疏零矩阵。然后,如果 x 等于未知值,我会将部分值设为 A_sparse

问题

  • 此代码正常工作,但有循环!我应该删除循环,但是 如何?

在这里,我举了下面的例子:

输入

  • DATA - 表示索引; [[24,20,21,22,23],[24,25,26,27],[25,26,27,23],[0,4,8,12,16,20]]
  • 部分 - [[1.16950604,0.08724138,1.5326188,1.5326188,0.74587448],           [0.44409055,1.51394507,1.51394507,0.95853188],           [0.77097384,1.77717041,0.14615981,0.185952],           [0.93,1.5,1.5,1.5,1.5,0.07]]

输出:   - A_sparse - 稀疏矩阵;

def get_sparse(DATA, PORTION):

    x = np.unique( flatten(DATA) )
    A = np.zeros((len(DATA), len(x)))

    for i in range(len(DATA)):
        for m1,m2 in enumerate(DATA[i]):
            for j,k in enumerate(x):
                    if float(m2) == float(k):
                            A[i][j] = PORTION[i][m1]
    return A


>>> get_sparse(DATA, PORTION)
array([[ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
     0.08724138,  1.5326188 ,  1.5326188 ,  0.74587448,  1.16950604,
     0.        ,  0.        ,  0.        ],
   [ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
     0.        ,  0.        ,  0.        ,  0.        ,  0.44409055,
     1.51394507,  1.51394507,  0.95883188],
   [ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
     0.        ,  0.        ,  0.        ,  0.185952  ,  0.        ,
     0.77097384,  1.77917041,  0.14615981],
   [ 0.93      ,  1.5       ,  1.5       ,  1.5       ,  1.5       ,
     0.07      ,  0.        ,  0.        ,  0.        ,  0.        ,
     0.        ,  0.        ,  0.        ]])

我在使用Python时经常不喜欢使用循环,所以,我想删除循环以使这段代码更短更快。 任何答案将不胜感激!

1 个答案:

答案 0 :(得分:1)

鉴于DATA和PORTION列表的不规则列表,这个问题的numpy向量化并不明显。但是,如果我打印get_sparse(DATA, DATA)

,它可以帮助我可视化构造函数
[[ 0  0  0  0  0 20 21 22 23 24  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 24 25 26 27]
 [ 0  0  0  0  0  0  0  0 23  0 25 26 27]
 [ 0  4  8 12 16 20  0  0  0  0  0  0  0]]

这些看起来像常规列号,除了第一个步骤4之外。此函数版本构建一个(4,28)数组,然后删除zero列。

def get_sparse(DATA, PORTION):
    x = np.unique(itertools.chain(*DATA) )
    A = np.zeros((len(DATA), max(x)+1))
    for a, d, p in zip(A, DATA, PORTION):
        a[d] = p
    return A[:,x]

要使用稀疏矩阵,请尝试:

from scipy import sparse
A = sparse.lil_matrix((4,28))
A.data = PORTION
A.rows = DATA

您的DATA和PORTION列表与lil_matrix类型的内部格式完全匹配。一旦构造A可以转换为其他稀疏类型之一用于数学或切片。 A.toarray()提供完整的“密集”形式。