[英]Numpy - Matrix multiplication
I spent about 2 hours trying to figure out what's going on, but for the life of me I can't figure out why switching the order of matrices when multiplying doesn't seem to work: 我花了大约2个小时试图弄清楚到底发生了什么,但是对于我一生来说,我无法弄清楚为什么在乘法时切换矩阵的顺序似乎不起作用:
Using Python 2.7x: 使用Python 2.7x:
import numpy as np
num_segments = 25
num_vintages = 24
# Create a 3d matrix 25 deep x 24r x 24c
mx_loans_new_loans = np.zeros((num_segments, num_vintages, num_vintages))
# Create the multiplication vector - same as the first dimension of 3d matrix
mult_vector = np.arange(10,35)
len(mult_vector)
The intent is to fill in the matrix on the diagonal with the mult_vector
. 目的是用
mult_vector
填充对角线上的mult_vector
。 Here is the part I can't wrap my head around. 这是我无法缠绕的部分。
This version does not fulfill the intent: 此版本不符合以下意图:
for (i, x) in enumerate(mx_loans_new_loans):
np.fill_diagonal(x, 1)
x = x * mult_vector[i]
The results still spit out just the original matrix with 1's on the diagonal. 结果仍然只吐出对角线为1的原始矩阵。
This version, however, does work. 但是,此版本确实有效。 All I've done is reverse the matrices in the
enumerate
: 我所要做的就是颠倒
enumerate
的矩阵:
for (i, x) in enumerate(mult_vector):
np.fill_diagonal(mx_loans_new_loans[i], 1)
mx_loans_new_loans[i] = mx_loans_new_loans[i] * x
Sidenote: I've since realized a more optimized version fills the intent: 旁注:从那以后,我意识到更优化的版本可以满足您的意图:
for (i, x) in enumerate(mx_loans_new_loans):
np.fill_diagonal(x, mult_vector[i])
But does anyone know why the first version doesn't work, but the second version does? 但是有人知道为什么第一个版本不起作用,而第二个版本却起作用吗? What am I missing?
我想念什么? Is this a broadcasting problem or something simpler?
这是广播问题还是更简单的东西?
mx_loans_new_loans
is 3d, (25,24,24). mx_loans_new_loans
是3d(25,24,24)。 x
in the loop is (24,24). 循环中的
x
为(24,24)。 multi_vector
is (25,); multi_vector
是(25,); multivector[i]
a scalar. multivector[i]
标量。
The fill_diagonal
sets the 1s in x
(in place). fill_diagonal
将x
设置为1(在适当位置)。 But x = x * mult_vector[i]
, replaces x
with a new array, and doesn't change the original. 但是
x = x * mult_vector[i]
,将x
替换为新数组,并且不更改原始数组。 That is, it reassigns variable x
. 即,它重新分配变量
x
。
x *= mult_vector[i]
should change the diagonals in the original array. 应该更改原始数组中的对角线。
mx_loans_new_loans[i] = ...
changes this subarray in place. mx_loans_new_loans[i] = ...
更改此子mx_loans_new_loans[i] = ...
位置。 Again mx_loans_new_loans[i] *= ...
should work as well. 同样,
mx_loans_new_loans[i] *= ...
应该工作。
With zip
we can iterate on both arrays: 使用
zip
我们可以在两个数组上进行迭代:
In [44]: Z=np.zeros((4,3,3),int)
In [45]: for i,j in zip(Z,np.arange(10,14)):
...: np.fill_diagonal(i,j)
...:
In [46]: Z
Out[46]:
array([[[10, 0, 0],
[ 0, 10, 0],
[ 0, 0, 10]],
[[11, 0, 0],
[ 0, 11, 0],
[ 0, 0, 11]],
[[12, 0, 0],
[ 0, 12, 0],
[ 0, 0, 12]],
[[13, 0, 0],
[ 0, 13, 0],
[ 0, 0, 13]]])
We can view all the diagonals as set in the loop with: 我们可以使用以下命令查看循环中设置的所有对角线:
In [47]: Z[:,np.arange(3),np.arange(3)]
Out[47]:
array([[10, 10, 10],
[11, 11, 11],
[12, 12, 12],
[13, 13, 13]])
And modify them with (not quite right): 并用(不太正确)修改它们:
In [48]: Z[:,np.arange(3),np.arange(3)]=np.arange(20,23)
In [49]: Z
Out[49]:
array([[[20, 0, 0],
[ 0, 21, 0],
[ 0, 0, 22]],
[[20, 0, 0],
[ 0, 21, 0],
[ 0, 0, 22]],
[[20, 0, 0],
[ 0, 21, 0],
[ 0, 0, 22]],
[[20, 0, 0],
[ 0, 21, 0],
[ 0, 0, 22]]])
better: 更好:
In [50]: Z[:,np.arange(3),np.arange(3)]=np.arange(20,24)[:,None]
In [51]: Z
Out[51]:
array([[[20, 0, 0],
[ 0, 20, 0],
[ 0, 0, 20]],
[[21, 0, 0],
[ 0, 21, 0],
[ 0, 0, 21]],
[[22, 0, 0],
[ 0, 22, 0],
[ 0, 0, 22]],
[[23, 0, 0],
[ 0, 23, 0],
[ 0, 0, 23]]])
Another example of how assignment changes arrays (or not): 分配如何更改(或不更改)数组的另一个示例:
In [97]: x = np.zeros((2,3),int)
y
is a view
, a way of looking at one row of x
: y
是一个view
,是view
x
一行的一种方式:
In [99]: y = x[0]
In [100]: id(y)
Out[100]: 2877147400
In-place change to y
appears as a change to x
: y
的就地更改显示为x
的更改:
In [101]: y += 3
In [102]: y
Out[102]: array([3, 3, 3])
In [103]: x
Out[103]:
array([[3, 3, 3],
[0, 0, 0]])
But a y=
change to y
breaks the connection. 但是将
y=
更改为y
会断开连接。 y
is no longer a view (row) of x
, but rather a whole new array. y
不再是x
的视图(行),而是一个全新的数组。
In [104]: y = y + 3
In [105]: y
Out[105]: array([6, 6, 6])
In [106]: x
Out[106]:
array([[3, 3, 3],
[0, 0, 0]])
In [107]: id(y)
Out[107]: 2876795264
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.