矢量化功能:apply_over_axes/apply_along_axis



我想计算m m*n维数组的mm子数组的行列式,并希望以更快/更优雅的方式做到这一点。暴力方法有效:

import numpy as n
array=n.array([[[0.,1.,2.,3.],[2,1,1,0]],[[0.5, 0.5,2,2],[0.5,1,0,2]]])
detarray=n.zeros(4)
for i in range(4):
detarray[i]= n.linalg.det(array[:,:,i])

我会尝试用apply_along_axis这样做,但我知道这仅适用于函数的 1D 参数,所以我认为我无法让它工作。

但是,我认为apply_over_axes也应该有效:

n.apply_over_axes(n.linalg.det, array, [0,1])

但这给了我一个错误: "det(( 正好需要 1 个参数(给定 2 个(">

有谁知道为什么这不起作用?如果这种类型的计算真的无法用apply_over_axes实现,那么有没有比for循环更好的方法呢?

利用 NumPy 对 3D 数组的转置语义,您可以简单地将转置数组传递给numpy.linalg.det(),如下所示:

In [13]: arr = np.array([[[0.,1.,2.,3.], 
[2, 1, 1, 0]], 
[[0.5, 0.5,2,2],
[0.5, 1, 0, 2]]])
In [14]: np.linalg.det(arr.T)
Out[14]: array([-1. ,  0.5, -2. ,  6. ])

性能方面,这种方法似乎比另一种使用numpy.moveaxis手动移动轴的方法快两倍

In [29]: %timeit np.linalg.det(np.moveaxis(arr, 2, 0))
12.9 µs ± 192 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [30]: %timeit np.linalg.det(arr.T)
6.2 µs ± 136 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

numpy.linalg.det开箱即用。您需要做的就是将外轴向左移动:

>>> np.linalg.det(np.moveaxis(array, 2, 0))
array([-1. ,  0.5, -2. ,  6. ])

最新更新