numpy-向量化功能:apply_over_axes / apply_along_axis

时间:2018-10-09 20:01:04

标签: python numpy numpy-broadcasting

我想计算m m * n维数组的m m个子数组的行列式,并希望以一种更快/更优雅的方式做到这一点。蛮力方法起作用:

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来完成此操作的,但是我知道这仅适用于该函数的一维参数,因此我想我无法使用它。

但是,我认为apply_over_axes也应该起作用:

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

但这给我一个错误: “ det()恰好接受1个参数(给定2个)”

有人知道为什么这行不通吗?如果使用apply_over_axes确实无法进行这种类型的计算,那么有没有比for循环更好的方法了?

2 个答案:

答案 0 :(得分:2)

利用transpose semantics of 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)

答案 1 :(得分:1)

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

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