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

Numpy:将矩阵与向量数组相乘,numpy,scipy,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]]) 但是,即使在谷歌搜索并尝试了两个多小时之后,我也无法从a和每个向量的矩阵乘法中得到结果向量。我知道quiver将分量长度作为输入,因此进入quiver函数的结果向量应该类

我很难进入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]])
但是,即使在谷歌搜索并尝试了两个多小时之后,我也无法从
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)

您可以使用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)
或者,如果要使用
np.dot
,则必须展平
X
Y
数组,并将它们组合成适当的形状,如下所示:

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)

我一直在努力解决同样的问题,最后使用了numpy.matrix类。考虑下面的例子。

import numpy as np

>>> transformation_matrix = np.array([(1, 0, 0, 1),
...                                   (0, 1, 0, 0),
...                                   (0, 0, 1, 0),
...                                   (0, 0, 0, 1)])
>>> coordinates = np.array([(0,0,0),
...                         (1,0,0)])
>>> coordinates = np.hstack((coordinates, np.ones((len(coordinates), 1))))
>>> coordinates
array([[ 0.,  0.,  0.,  0.],
       [ 1.,  0.,  0.,  0.]])
在这种情况下,numpy.matrix类会有所帮助。下面的代码通过将坐标转换为列向量和numpy.matrix类的指定矩阵乘法重载,给出了预期的结果

>>> (np.asmatrix(transformation_matrix) * np.asmatrix(coordinates).T).T
matrix([[ 1.,  0.,  0.,  1.],
        [ 2.,  0.,  0.,  1.]])
因为,对于多维数据,
np.mul
(或
@
)的工作方式如下:

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

dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
这不是我们想要的。然而,有一些简单的替代方案不涉及展平-非平坦或手动矩阵乘法:
np.tensordot
np.einsum

第一个例子直接取自:

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

第二个是simple
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)

你期望结果是什么样的<代码>a.shape=(2,2),X.shape=(10,5),Y.shape=(10,5)。我不明白你的意思…你能在一个循环中展示一个简单的版本吗(让它更容易理解你想做什么)?完成了。这实际上只是向量场上的一个矩阵,箭袋箭头所显示的结果我给出了一个关于做这种点积的答案,可能对你有帮助。嗯,我很感激。但这两种情况都非常有限,对吗?首先是手写的矩阵乘法。这是相当粗糙的,对于任何更高的维度都不起作用。第二种是依赖于零。这两种情况都适用于2D。对于3D,它应该类似于
U,V,W=np.dot(a-np.eye(3),[X.ravel(),Y.ravel(),Z.ravel())
为什么您首先将它们定义为数组,后来才将它们转换为矩阵?你本可以做
转换\u matrix=np.matrix([(1,0,0,1,0,0,0),(0,0,0,1,0),(0,0,0,0,1)])
@R.Navega这是真的,因为OP是在
ndarray
上运行的。请注意,
asmatrix()
不会复制数据:“与矩阵不同,如果输入已经是矩阵或ndarray,asmatrix不会复制。等效于矩阵(数据,copy=False)。”
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)