【问题标题】:Calculate the angle between the rows of two matrices in numpy在numpy中计算两个矩阵的行之间的角度
【发布时间】:2018-11-19 04:41:45
【问题描述】:

我有两个由 3d 向量(numpy 1D 数组)组成的矩阵,我需要逐行计算向量之间的角度,并将结果返回到 1d 数组中。我知道如何计算两个一维向量之间的角度。这样做的正确方法是什么?

*** 结果角度的单位是度数而不是弧度。

现在我有了这个:

import numpy as np

A = np.array([[1,0,0],
              [0,1,0],
              [0,0,1]])

B = np.array([[1,0,1],
              [1,1,0],
              [0,1,0]])

def angle(V1,V2):
    """
    angle between vectors V1 and V2 in degrees using
    angle = arccos ( V1 dot V2 / norm(V1) * norm(V2) ) *180/np.pi
    """

    cos_of_angle = V1.dot(V2) / (np.linalg.norm(V1) * np.linalg.norm(V2)) 
    return np.arccos(np.clip(cos_of_angle,-1,1))  * 180/np.pi

注意从 rad 到 deg 转换的比例项 180/np.pi。

我想要一个数组:

C = [ angle(A[0],B[0]) , angle(A[1],B[1])...... and so on]

如果有人可以提供帮助,我真的很感激。

【问题讨论】:

  • 缩进和括号看起来不对。如果需要,请查看并进一步编辑。
  • 已更正。谢谢@Divakar

标签: python numpy matrix vector angle


【解决方案1】:

我们可以使用einsum 来替换点积计算,并使用axis 参数来替换norm 的参数来获得矢量化解决方案,就像这样 -

def angle_rowwise(A, B):
    p1 = np.einsum('ij,ij->i',A,B)
    p2 = np.linalg.norm(A,axis=1)
    p3 = np.linalg.norm(B,axis=1)
    p4 = p1 / (p2*p3)
    return np.arccos(np.clip(p4,-1.0,1.0))

我们可以进一步优化并引入更多einsum,专门用于计算norms。因此,我们可以这样使用它 -

def angle_rowwise_v2(A, B):
    p1 = np.einsum('ij,ij->i',A,B)
    p2 = np.einsum('ij,ij->i',A,A)
    p3 = np.einsum('ij,ij->i',B,B)
    p4 = p1 / np.sqrt(p2*p3)
    return np.arccos(np.clip(p4,-1.0,1.0))

因此,为了解决我们的情况,以度为单位获得输出 -

out = angle_rowwise(A, B)*180/np.pi

【讨论】:

  • 这些角度是相对于原点 (0, 0, 0) 的吗?我正在尝试将这个想法转化为使用 3D 点。
  • @NaN 我不太确定那里的理论。我只是专注于将其转换为矢量化代码。
  • 它一定是不同的,因为你得到的结果与这里的实现不同 stackoverflow.com/questions/2827393/… a = np.array([[1, 0, 0], [1, 0, 0], [1 , 0, 0]]) 和 b = np.array([[1, 0, 0], [0, 1, 0], [0, -1, 0]]) 来表示相同、相同和相反的方向向量配对
  • @NaN 该实现看起来与 OP 在此处发布的不同。我在这里关注这个。
  • 亲爱的朋友,感谢您的帮助。我编辑了原始帖子,因为我注意到我忘记在角度函数的返回语句中包含 np.arccos。正如@Nan 所指出的,我已经包含了 (stackoverflow.com/questions/2827393/…) 建议的更正,如果是并行向量,则会返回 Nan。
【解决方案2】:

如果您正在使用 3D 矢量,则可以使用工具带 vg 简洁地执行此操作。它是 numpy 之上的一个轻量层,它同样适用于单个向量和向量堆栈。

import numpy as np
import vg

A = np.array([[1,0,0],
              [0,1,0],
              [0,0,1]])

B = np.array([[1,0,1],
              [1,1,0],
              [0,1,0]])

vg.angle(A, B)

我在上次创业时创建了这个库,它的动机是这样的:在 NumPy 中冗长或不透明的简单想法。

【讨论】:

    猜你喜欢
    • 2016-04-16
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多