【问题标题】:Is there a way to use numpy to apply a function to a 2D array without a loop有没有办法使用 numpy 将函数应用于没有循环的二维数组
【发布时间】:2019-12-31 18:13:52
【问题描述】:

我正在尝试使用 Transforms3d python 包将四元数列表转换为相应的方向矩阵。

每个四元数是输入的 4 元素列表/数组,使用 transforms3d.quaternions.quat2mat(q) 函数返回 3x3 方向矩阵。

我有一些需要转换的 10K-100K 四元数列表(nx4 数组),虽然使用循环很容易做到这一点,但我认为如果有某种方法可以将过程向量化,它可能会更快。

一些搜索建议我可以简单地执行类似 np.vectorize() 的操作,但我正在努力完成这项工作。列表理解工作正常,但我想 numpy 向量解决方案会快得多。


orientations = np.array([[ 0.6594993 , -0.06402525, -0.74797227, -0.03871606],
       [ 0.78091967, -0.15961452, -0.44240183, -0.41105753]])

rotMatrix = [quat2mat(orient) for orient in orientations]

vfunc=np.vectorize(quat2mat, signature='(m,n)->()')

vfunc(orientations)

不幸的是,我什至无法运行 numpy 版本,无论有无签名(这可能是错误的)。

> Traceback(最近一次调用最后一次):

文件“”,第 1 行,在 vfunc(aa)

调用中的文件“c:\wpy64-3740\python-3.7.4.amd64\lib\site-packages\numpy\lib\function_base.py”,第 2091 行 return self._vectorize_call(func=func, args=vargs)

文件“c:\wpy64-3740\python-3.7.4.amd64\lib\site-packages\numpy\lib\function_base.py”,第 2157 行,在 _vectorize_call res = self._vectorize_call_with_signature(func, args)

文件“c:\wpy64-3740\python-3.7.4.amd64\lib\site-packages\numpy\lib\function_base.py”,第 2198 行,在 _vectorize_call_with_signature 结果 = func(*(arg[index] for args))

文件“c:\wpy64-3740\python-3.7.4.amd64\lib\site-packages\transforms3d\quaternions.py”,第 133 行,在 quat2mat w, x, y, z = q

ValueError: 没有足够的值来解包(预期 4,得到 2)

【问题讨论】:

  • np.vectorize 并不快;至少阅读文档到您看到免责声明的程度。我还想说它传递了标量值,但我看到你使用的是signature。我测试了几次该模式;使用起来有点棘手,甚至比普通模式还要慢。
  • 关于vectorize 的另一个说明 - 当您有多个需要相互广播的输入数组时,它最有用。对于一个数组和一维,简单的迭代更简单。真正的numpy 矢量化的关键在于quat2mat,而不是你可以环绕它的东西。每次调用该函数都会花费时间。
  • @hpaulj 感谢您指出免责声明 - 我完全错过了它。是的,看来我必须深入了解quat2mat 才能加快速度。

标签: numpy vectorization numpy-ufunc


【解决方案1】:

正如建议的那样,提高性能的最佳方法是向量化 quat2mat,结果 (%timeit) 支持:

quat2mat() 循环使用 2000 个四元数:

17.3 ms ± 482 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

用于 2000 个四元数的向量化 quat2mat_array():

1.11 ms ± 16.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

应该先这样做,而不是惹np.vectorise()!感谢您重新关注!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    相关资源
    最近更新 更多