Numpy:将矩阵与向量数组相乘

Bas*_*sti 5 numpy scipy

我很难进入 numpy。我最终想要的是一个简单的由矩阵变换的向量的箭袋图。我已经阅读了很多次,只是将数组用于矩阵,这很公平。我有一个用于 x 和 y 坐标的网格

X,Y = np.meshgrid( np.arange(0,10,2),np.arange(0,10,1) )
a = np.array([[1,0],[0,1.1]])
Run Code Online (Sandbox Code Playgroud)

但即使在谷歌搜索并尝试了两个多小时之后,我也无法从a每个向量的矩阵乘法中得到结果向量。我知道 quiver 将分量长度作为输入,因此进入 quiver 函数的结果向量应该类似于np.dot(a, [X[i,j], Y[i,j]]) - X[i,j]x 分量,其中 i 和 j 在范围内迭代。

我当然可以在循环中对其进行编程,但是 numpy 有很多内置工具可以使这些矢量化的东西变得方便,我相信有更好的方法。

编辑:好的,这是循环版本。

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(10,10))

n=10
X,Y = np.meshgrid( np.arange(-5,5),np.arange(-5,5) )
print("val test", X[5,3])
a = np.array([[0.5,0],[0,1.3]])
U = np.zeros((n,n))
V = np.zeros((n,n))
for i in range(10):
    for j in range(10):
        product = np.dot(a, [X[i,j], Y[i,j]]) #matrix with vector
        U[i,j] = product[0]-X[i,j]  # have to substract the position since quiver accepts magnitudes
        V[i,j] = product[1]-Y[i,j]

Q = plt.quiver( X,Y, U, V)
Run Code Online (Sandbox Code Playgroud)

Ond*_*dro 6

您可以使用 NumPy 广播“手动”进行矩阵乘法,如下所示:

import numpy as np
import matplotlib.pyplot as plt

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5))
a = np.array([[0.5, 0], [0, 1.3]])

U = (a[0,0] - 1)*X + a[0,1]*Y
V = a[1,0]*X + (a[1,1] - 1)*Y

Q = plt.quiver(X, Y, U, V)
Run Code Online (Sandbox Code Playgroud)

或者,如果您想使用,np.dot您必须将您的XY数组展平并将它们组合成适当的形状,如下所示:

import numpy as np
import matplotlib.pyplot as plt

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5))
a = np.array([[0.5, 0], [0, 1.3]])

U,V = np.dot(a-np.eye(2), [X.ravel(), Y.ravel()])

Q = plt.quiver(X, Y, U, V)
Run Code Online (Sandbox Code Playgroud)


Ily*_*rov 5

正如文档所说,对于多维数据np.mul(或@)按以下方式工作:

对于 N 维,它是 a 的最后一个轴与 b 的倒数第二个轴的和积:

dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
Run Code Online (Sandbox Code Playgroud)

这不是我们想要的。然而,有一些简单的替代方案,不涉及展平-反展平或手动矩阵乘法:np.tensordotnp.einsum

第一个是直接取自文档的示例:

要使用最左边的索引而不是最右边的索引进行矩阵-矩阵乘积,您可以执行以下操作np.einsum('ij...,jk...->ik...', a, b)

import numpy as np
import matplotlib.pyplot as plt

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5))
a = np.array([[0.5, 0], [0, 1.3]])

U, V = np.einsum('ij...,jk...->ik...', a - np.eye(2), np.array([X, Y]))
Q = plt.quiver(X, Y, U, V)
Run Code Online (Sandbox Code Playgroud)

二是应用简单np.tensordot。我们只是教它对第一个参数的第二个轴(列)和第一个参数的第一个轴(行)求和。

import numpy as np
import matplotlib.pyplot as plt

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5))
a = np.array([[0.5, 0], [0, 1.3]])

U, V = np.tensordot(a - np.eye(2), np.array([X, Y]), axes=(1, 0))
plt.quiver(X, Y, U, V)
Run Code Online (Sandbox Code Playgroud)