简体   繁体   English

带有邻接矩阵的乘法和点积(numpy)

[英]Multiplication and dot product with adjacency matrices (numpy)

I am using the following chunk of code with networkx, when I discovered the following oddity. 当我发现以下奇怪之处时,我在networkx中使用了以下代码块。 In the first case, I used the ufunc multiply(*) on a sparse matrix that unexpectedly correctly giving me a degree sequence. 在第一种情况下,我在稀疏矩阵上使用了ufuncmultiple(*),该矩阵出乎意料地正确地给出了一个度序列。 However, when the same is done with an ordinary matrix, it is giving me a 10 x 10 matrix, and as expected np.dot(...) is giving me the correct result. 但是,当用普通矩阵完成相同操作时,它给了我10 x 10的矩阵,并且正如预期的那样np.dot(...)给了我正确的结果。

import numpy as np
import networks as nx

ba = nx.barabasi_albert_graph(n=10, m=2)

A = nx.adjacency_matrix(ba)
# <10x10 sparse matrix of type '<class 'numpy.int64'>'
# with 32 stored elements in Compressed Sparse Row format>

A * np.ones(10)

# output: array([ 5.,  3.,  4.,  5.,  4.,  3.,  2.,  2.,  2.,  2.])

nx.degree(ba)

# output {0: 5, 1: 3, 2: 4, 3: 5, 4: 4, 5: 3, 6: 2, 7: 2, 8: 2, 9: 2}

B = np.ones(100).reshape(10, 10)

B * np.ones(10)

array([[ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.]])

np.dot(B, np.ones(10))
# array([ 10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.])

I was expecting that I should be doing np.dot(A, np.ones(10)) but that returns an array of 10, 10 x 10 matrices 我原以为我应该做np.dot(A, np.ones(10))但那会返回10、10 x 10矩阵的数组

array([ <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>,
   <10x10 sparse matrix of type '<class 'numpy.float64'>'
with 32 stored elements in Compressed Sparse Row format>], dtype=object)

What is the nuance here? 这有什么细微差别?

For regular numpy arrays, * multiply is element by element (with broadcasting ). 对于常规的numpy数组, *乘元素是一个元素一个元素(带有broadcasting )。 np.dot is the matrix product, the sum-of-products. np.dot是矩阵乘积,即乘积之和。 For the np.matrix subclass * is the matrix product, the dot . 对于np.matrix子类*是矩阵乘积,即dot sparse.matrix is not a subclass, but it is modeled on that. sparse.matrix不是子类,但它是基于它的模型。 * is the matrix product. *是矩阵乘积。

In [694]: A = sparse.random(10,10,.2, format='csr')
In [695]: A
Out[695]: 
<10x10 sparse matrix of type '<class 'numpy.float64'>'
    with 20 stored elements in Compressed Sparse Row format>
In [696]: A *np.ones(10)
Out[696]: 
array([ 0.6349177 ,  0.        ,  1.25781168,  1.12021258,  2.43477065,
        1.10407149,  1.95096264,  0.6253589 ,  0.44242708,  0.50353061])

The sparse matrix has the dot method, which behaves the same: 稀疏矩阵具有dot方法,其行为相同:

In [698]: A.dot(np.ones(10))
Out[698]: 
array([ 0.6349177 ,  0.        ,  1.25781168,  1.12021258,  2.43477065,
        1.10407149,  1.95096264,  0.6253589 ,  0.44242708,  0.50353061])

The dense version: 密集版本:

In [699]: np.dot(A.A,np.ones(10))
Out[699]: 
array([ 0.6349177 ,  0.        ,  1.25781168,  1.12021258,  2.43477065,
        1.10407149,  1.95096264,  0.6253589 ,  0.44242708,  0.50353061])

I thought np.dot was supposed to handle sparse matrices right, that is differ to their own method. 我以为np.dot应该处理正确的稀疏矩阵,这与它们自己的方法不同。 But np.dot(A,np.ones(10)) does not do that right, producing the object array of 2 sparse matrices. 但是np.dot(A,np.ones(10))不能做到这一点,从而生成2个稀疏矩阵的对象数组。 I can dig into why, but for now, avoid it. 我可以找出原因,但现在就避免。

In general, use sparse functions and methods with sparse matrices. 通常,将稀疏函数和方法与稀疏矩阵一起使用。 Don't assume numpy functions will have them correctly. 不要以为numpy函数可以正确使用它们。


np.dot works fine when both arrays are sparse, 当两个数组都稀疏时, np.dot可以正常工作,

In [702]: np.dot(A,A)
Out[702]: 
<10x10 sparse matrix of type '<class 'numpy.float64'>'
    with 32 stored elements in Compressed Sparse Row format>
In [703]: np.dot(A,A.T)
Out[703]: 
<10x10 sparse matrix of type '<class 'numpy.float64'>'
    with 31 stored elements in Compressed Sparse Row format>

In [705]: np.dot(A, sparse.csr_matrix(np.ones(10)).T)
Out[705]: 
<10x1 sparse matrix of type '<class 'numpy.float64'>'
    with 9 stored elements in Compressed Sparse Row format>
In [706]: _.A
Out[706]: 
array([[ 0.6349177 ],
       [ 0.        ],
       [ 1.25781168],
       [ 1.12021258],
       [ 2.43477065],
       [ 1.10407149],
       [ 1.95096264],
       [ 0.6253589 ],
       [ 0.44242708],
       [ 0.50353061]])

For what it's worth the sparse sum is performed with this kind of matrix product: 对于稀疏sum来说,用这种矩阵乘积执行sum是什么:

In [708]: A.sum(axis=1)
Out[708]: 
matrix([[ 0.6349177 ],
        [ 0.        ],
        [ 1.25781168],
        [ 1.12021258],
        [ 2.43477065],
        [ 1.10407149],
        [ 1.95096264],
        [ 0.6253589 ],
        [ 0.44242708],
        [ 0.50353061]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM