基于索引的带numpy的点积
我试图优化一个转换问题,让numpy尽可能多地完成繁重的工作 在我的例子中,我有一系列的坐标集,每个坐标集都必须用相应的索引滚动/俯仰/偏航值点着 从程序上看,它是这样的:基于索引的带numpy的点积,numpy,coordinate-transformation,Numpy,Coordinate Transformation,我试图优化一个转换问题,让numpy尽可能多地完成繁重的工作 在我的例子中,我有一系列的坐标集,每个坐标集都必须用相应的索引滚动/俯仰/偏航值点着 从程序上看,它是这样的: In [1]: import numpy as np ...: from ds.tools.math import rotation_array ...: from math import pi ...: ...: rpy1 = rotation_array(pi, 0.001232, 1.
In [1]: import numpy as np
...: from ds.tools.math import rotation_array
...: from math import pi
...:
...: rpy1 = rotation_array(pi, 0.001232, 1.234243)
...: rpy2 = rotation_array(pi/1, 1.325, 0.5674543)
In [2]: rpy1
Out[2]:
array([[ 3.30235500e-01, 9.43897768e-01, -1.23199969e-03],
[ 9.43898485e-01, -3.30235750e-01, 1.22464587e-16],
[-4.06850342e-04, -1.16288264e-03, -9.99999241e-01]])
In [3]: rpy2
Out[3]:
array([[ 2.05192356e-01, 1.30786082e-01, -9.69943863e-01],
[ 5.37487075e-01, -8.43271987e-01, 2.97991829e-17],
[-8.17926489e-01, -5.21332290e-01, -2.43328794e-01]])
...:
...: a1 = np.array([[-9.64996132, -5.42488639, -3.08443],
...: [-8.08814188, -4.56431952, -3.01381]])
...:
...: a2 = np.array([[-6.91346292, -3.91137259, -2.82621],
...: [-4.34534536, -2.34535546, -4.87692]])
然后我用rpy1和rpy2分别点a1和a2中的坐标
In [4]: a1.dot(rpy1)
Out[4]:
array([[-8.30604694, -7.31349869, 3.09631641],
[-6.97801968, -6.12357288, 3.0237723 ]])
In [5]: a2.dot(rpy2)
Out[5]:
array([[-1.20926993, 3.86756074, 7.3933692 ],
[ 1.83673215, 3.95195774, 5.40143613]])
我希望在一个操作中完成全部工作,而不是遍历a和rpy的列表。所以我希望下面的代码能达到这个效果,这样a12中的每一组坐标都会被rpy_a中相应的索引数组所点缀
但很明显,从产出中我得到了比我期望的更多的东西:
In [6]: rpy_a = np.array([rpy1, rpy2])
...:
...: a12 = np.array([a1, a2])
In [7]: a12.dot(rpy_a)
Out[7]:
array([[[[-8.30604694, -7.31349869, 3.09631641],
[-2.37306761, 4.92058705, 10.1104514 ]],
[[-6.97801968, -6.12357288, 3.0237723 ],
[-1.6478126 , 4.36234287, 8.57839034]]],
[[[-5.9738597 , -5.23064061, 2.83472524],
[-1.20926993, 3.86756074, 7.3933692 ]],
[[-3.64678058, -3.32137028, 4.88226976],
[ 1.83673215, 3.95195774, 5.40143613]]]])
我需要的是:
array([[[-8.30604694, -7.31349869, 3.09631641],
[-6.97801968, -6.12357288, 3.0237723 ]],
[[-1.20926993, 3.86756074, 7.3933692 ],
[ 1.83673215, 3.95195774, 5.40143613]]])
有人能告诉我如何做到这一点吗
编辑:
可运行示例:
import numpy as np
rpy1 = np.array([[ 3.30235500e-01, 9.43897768e-01, -1.23199969e-03],
[ 9.43898485e-01, -3.30235750e-01, 1.22464587e-16],
[-4.06850342e-04, -1.16288264e-03, -9.99999241e-01]])
rpy2 = np.array([[ 2.05192356e-01, 1.30786082e-01, -9.69943863e-01],
[ 5.37487075e-01, -8.43271987e-01, 2.97991829e-17],
[-8.17926489e-01, -5.21332290e-01, -2.43328794e-01]])
a1 = np.array([[-9.64996132, -5.42488639, -3.08443],
[-8.08814188, -4.56431952, -3.01381]])
a2 = np.array([[-6.91346292, -3.91137259, -2.82621],
[-4.34534536, -2.34535546, -4.87692]])
print(a1.dot(rpy1))
# array([[-8.30604694, -7.31349869, 3.09631641],
# [-6.97801968, -6.12357288, 3.0237723 ]])
print(a2.dot(rpy2))
# array([[-1.20926993, 3.86756074, 7.3933692 ],
# [ 1.83673215, 3.95195774, 5.40143613]])
rpy_a = np.array([rpy1, rpy2])
a12 = np.array([a1, a2])
print(a12.dot(rpy_a))
# Result:
# array([[[[-8.30604694, -7.31349869, 3.09631641],
# [-2.37306761, 4.92058705, 10.1104514 ]],
# [[-6.97801968, -6.12357288, 3.0237723 ],
# [-1.6478126 , 4.36234287, 8.57839034]]],
# [[[-5.9738597 , -5.23064061, 2.83472524],
# [-1.20926993, 3.86756074, 7.3933692 ]],
# [[-3.64678058, -3.32137028, 4.88226976],
# [ 1.83673215, 3.95195774, 5.40143613]]]])
# Need:
# array([[[-8.30604694, -7.31349869, 3.09631641],
# [-6.97801968, -6.12357288, 3.0237723 ]],
# [[-1.20926993, 3.86756074, 7.3933692 ],
# [ 1.83673215, 3.95195774, 5.40143613]]])
假设您想要处理任意数量的数组
rpy1,rpy2,…,rpyn
和a1,a2,…,an
,我建议使用显式广播进行显式第一轴连接,只是因为“显式优于隐式”:
这等于:
a12 = np.array([a1, a2])
rpy_a = np.array([rpy1, rpy2])
np.array
需要更少的代码,也比我的显式方法更快,但我喜欢显式定义轴,这样每个阅读代码的人都可以猜测结果形状,而无需执行它
无论您选择哪条道路,重要的部分如下:
np.einsum('jnk,jkm->jnm', a12, rpy_a)
# Out:
array([[[-8.30604694, -7.3134987 , 3.09631641],
[-6.97801969, -6.12357288, 3.0237723 ]],
[[-1.20926993, 3.86756074, 7.3933692 ],
[ 1.83673215, 3.95195774, 5.40143613]]])
使用爱因斯坦求和约定,您可以定义要沿特定轴执行的np.matmul
(对于二维数组等于np.dot
)
在这种情况下,我们将连接轴j
(或第一尺寸或轴0)定义为共享轴,沿着该轴执行操作'nk,km->nm'
(等于,请参见out
参数中的签名描述)
也可以简单地使用np.matmul
(或python操作符@
)获得相同的结果:
np.matmul(a12, rpy_a)
a12 @ rpy_a
但同样:对于连接轴或形状可能发生变化的一般情况,更明确的
np.einsum
更可取。如果您知道不会对形状等进行任何更改,则应首选np.matmul
(代码更少,速度更快)。假设您希望处理任意数量的数组rpy1,rpy2,…,rpyn
和a1,a2,…,an
,我建议使用显式广播进行显式第一轴连接,仅仅因为“显式优于隐式”:
这等于:
a12 = np.array([a1, a2])
rpy_a = np.array([rpy1, rpy2])
np.array
需要更少的代码,也比我的显式方法更快,但我喜欢显式定义轴,这样每个阅读代码的人都可以猜测结果形状,而无需执行它
无论您选择哪条道路,重要的部分如下:
np.einsum('jnk,jkm->jnm', a12, rpy_a)
# Out:
array([[[-8.30604694, -7.3134987 , 3.09631641],
[-6.97801969, -6.12357288, 3.0237723 ]],
[[-1.20926993, 3.86756074, 7.3933692 ],
[ 1.83673215, 3.95195774, 5.40143613]]])
使用爱因斯坦求和约定,您可以定义要沿特定轴执行的np.matmul
(对于二维数组等于np.dot
)
在这种情况下,我们将连接轴j
(或第一尺寸或轴0)定义为共享轴,沿着该轴执行操作'nk,km->nm'
(等于,请参见out
参数中的签名描述)
也可以简单地使用np.matmul
(或python操作符@
)获得相同的结果:
np.matmul(a12, rpy_a)
a12 @ rpy_a
但同样:对于连接轴或形状可能发生变化的一般情况,更明确的
np.einsum
更可取。如果您知道不会对形状等进行任何更改,则应首选np.matmul
(代码越少,速度越快)。能否请您展示rpy1
和rpy2
的示例?模块ds
不可用(至少我无法导入和/或在pip上找到它)。rpy
a 3x3,Euler旋转矩阵?我在上面添加了rpy1和rpy2-非常感谢!您也可以将其添加为可执行代码添加可运行示例能否显示rpy1
和rpy2
的示例?模块ds
不可用(至少我无法导入和/或在pip上找到它)。rpy
a 3x3,Euler旋转矩阵?我在上面添加了rpy1和rpy2-非常感谢!您也可以将其添加为可执行代码添加可运行示例np。堆栈
与初始的串联
代码重复。@hpaulj是的,谢谢您的提醒。这将大大减少显式部分。:)<代码>np。堆栈与初始的串联代码重复。@hpaulj是的,谢谢您的提醒。这将大大减少显式部分。:)