邻接矩阵的乘法和点积(numpy)
Multiplication and dot product with adjacency matrices (numpy)
当我发现以下奇怪之处时,我正在将以下代码块与 networkx 一起使用。在第一种情况下,我在一个稀疏矩阵上使用了 ufunc multiply(*),它意外地正确地给出了一个度数序列。但是,当对普通矩阵执行相同操作时,它会给我一个 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.])
我原以为我应该做 np.dot(A, np.ones(10))
但是 returns 一个 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)
这里有什么细微差别?
对于常规的 numpy 数组,*
乘以一个元素一个元素(使用 broadcasting
)。 np.dot
是矩阵乘积,乘积和。对于np.matrix
子类*
是矩阵乘积,dot
。 sparse.matrix
不是子类,但它是以此为蓝本的。 *
是矩阵乘积。
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])
稀疏矩阵有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])
密集版:
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])
我认为np.dot
应该可以正确处理稀疏矩阵,这与他们自己的方法不同。但是 np.dot(A,np.ones(10))
做的不对,生成了 2 个稀疏矩阵的对象数组。我可以深入了解原因,但现在,请避免使用它。
一般来说,对稀疏矩阵使用稀疏函数和方法。不要假设 numpy
函数会正确地使用它们。
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]])
稀疏 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]])
当我发现以下奇怪之处时,我正在将以下代码块与 networkx 一起使用。在第一种情况下,我在一个稀疏矩阵上使用了 ufunc multiply(*),它意外地正确地给出了一个度数序列。但是,当对普通矩阵执行相同操作时,它会给我一个 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.])
我原以为我应该做 np.dot(A, np.ones(10))
但是 returns 一个 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)
这里有什么细微差别?
对于常规的 numpy 数组,*
乘以一个元素一个元素(使用 broadcasting
)。 np.dot
是矩阵乘积,乘积和。对于np.matrix
子类*
是矩阵乘积,dot
。 sparse.matrix
不是子类,但它是以此为蓝本的。 *
是矩阵乘积。
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])
稀疏矩阵有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])
密集版:
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])
我认为np.dot
应该可以正确处理稀疏矩阵,这与他们自己的方法不同。但是 np.dot(A,np.ones(10))
做的不对,生成了 2 个稀疏矩阵的对象数组。我可以深入了解原因,但现在,请避免使用它。
一般来说,对稀疏矩阵使用稀疏函数和方法。不要假设 numpy
函数会正确地使用它们。
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]])
稀疏 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]])