规范化矩阵行scipy矩阵

时间:2015-05-15 13:21:13

标签: python-2.7 scipy

我希望对从networkx有向图获得的稀疏scipy矩阵的每一行进行规范化。

 import networkx as nx
 import numpy as np

G=nx.random_geometric_graph(10,0.3)
M=nx.to_scipy_sparse_matrix(G, nodelist=G.nodes())

from __future__ import division

 print(M[3])
  (0, 1)        1
  (0, 5)        1

print(M[3].multiply(1/M[3].sum()))                                                                                                                                                                                                                                         
  (0, 1)        0.5
  (0, 5)        0.5

这没关系,我像往常一样正常化,并且按照预期正常工作。 但如果我写:

>>> M[3]=M[3].multiply(1/M[3].sum())
>>> M[3]
<1x10 sparse matrix of type '<type 'numpy.int64'>'
        with 10 stored elements in Compressed Sparse Row format>
  (0, 0)        0
  (0, 1)        0
  (0, 2)        0
  (0, 3)        0
  (0, 4)        0
  (0, 5)        0
  (0, 6)        0
  (0, 7)        0
  (0, 8)        0
  (0, 9)        0

我只需要迭代每一行并在这个稀疏的scipy矩阵上进行标准化。 你会怎么做? 感谢

2 个答案:

答案 0 :(得分:1)

这是一种方法(来自networkx.pagerank_scipy)。它使用scipy线性代数函数而不是遍历每一行。对于大型图表,这可能会更快。

function RetrieveDSOData(whatchannels: Byte; DSOCH1, DSOCH2: PDouble; LADATA: PWord; Nth_Sample: Byte): longint; cdecl; external 'E_l80.dll'; 

答案 1 :(得分:1)

原因

print(M[3].multiply(1/M[3].sum())) 

产生预期结果,

M[3]=M[3].multiply(1/M[3].sum())

生成零是因为M是整数数组<type 'numpy.int64'>。只要我们不尝试将规范分配回M,这不是问题。

如果M.A

array([[0, 1, 0, 1, 1],
       [1, 0, 0, 0, 1],
       [0, 0, 0, 1, 1],
       [1, 0, 1, 0, 1],
       [1, 1, 1, 1, 0]], dtype=int32)

列的总和是:Msum = M.sum(axis=1)。它很密集

matrix([[3],
        [2],
        [2],
        [3],
        [4]], dtype=int32)

与其相反:

Mnorm = 1/Msum
matrix([[ 0.33333333],
        [ 0.5       ],
        [ 0.5       ],
        [ 0.33333333],
        [ 0.25      ]])

M.multiply(Mnorm)密集(只是设置M.multiply的方式)。但使规范稀疏,产品也稀疏

M1 = M.multiply(sparse.csr_matrix(Mnorm))
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 14 stored elements in Compressed Sparse Row format>
M1.A
array([[ 0.        ,  0.33333333,  0.        ,  0.33333333,  0.33333333],
       [ 0.5       ,  0.        ,  0.        ,  0.        ,  0.5       ],
       [ 0.        ,  0.        ,  0.        ,  0.5       ,  0.5       ],
       [ 0.33333333,  0.        ,  0.33333333,  0.        ,  0.33333333],
       [ 0.25      ,  0.25      ,  0.25      ,  0.25      ,  0.        ]])

等效密集numpy操作是:

A = M.A
A/np.sum(A, axis=1, keepdims=True)