首页 文章

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

提问于
浏览
2

我很难进入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函数的结果向量应该类似于x-component的 np.dot(a, [X[i,j], Y[i,j]]) - X[i,j] ,其中i和j迭代范围 .

我当然可以在一个循环中编程,但numpy有很多内置工具来使这些矢量化的东西方便,我相信这是一个更好的方法 .

edit :好的,这是循环版本 .

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)

3 回答

  • 0

    您可以使用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 ,你必须压扁 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)
    
  • 4

    作为docs says,对于多维数据 np.mul (或 @ ),可以按以下方式工作:

    对于N维,它是a的最后一个轴上的和积和b的倒数第二个:dot(a,b)[i,j,k,m] = sum(a [i,j,: ] * b [k,:,m])

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

    第一个是直接从the docs获取的示例:

    使用最左边的索引而不是最右边的矩阵矩阵产品,你可以做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)
    

    第二个是简单 np.tensordot 的应用 . 我们只是教它将第一个参数的第二轴(colums)和第一个参数的第一个轴(行)相加 .

    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)
    
  • 2

    我一直在努力解决同样的问题,最后使用了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.]])
    

相关问题