在特定轴上运行的Numpy Power ufunc

时间:2019-04-18 15:04:17

标签: python numpy numpy-ufunc

我觉得numpy.power没有轴参数很奇怪...是因为有一种更好/更安全的方法来实现相同的目标(将3D数组中的每个2D数组提升为1D数组的幂)

假设您有一个(3,10,10)数组(A),并且想要将每个(10,10)数组提升到形状为(3,)的数组B中元素的幂。 您应该可以使用np.power(A,B,axis=0)来做到这一点,对吧? 但是,它会产生以下TypeError:

TypeError: 'axis' is an invalid keyword to ufunc 'power'

由于功率似乎没有轴或轴参数(尽管是ufunc),所以首选的方式是什么?

使用ufunc.reduce方法可能有解决方案,但我真的不知道如何使用numpy.power ...

现在我要做:

np.array([A[i,:,:]**B[i] for i in range(3)])

但是它看起来很丑,效率可能不如numpy方法。

谢谢

1 个答案:

答案 0 :(得分:4)

power不是 reduction 操作:它不会将数字的集合减少为一个数字,因此axis参数是没有意义的。 summax之类的操作是归约,因此指定沿其应用归约的轴很有意义。

所需的操作是broadcasting。这是一个较小的示例,其中A的形状为(3,2,2),B的形状为(3,)。我们无法编写np.power(A, B),因为这些形状与广播不兼容。我们首先必须向B添加平凡的尺寸以使其具有形状(3,1,1)。例如,可以使用B[:, np.newaxis, np.newaxis]B.reshape(-1, 1, 1)

In [100]: A                                                                                                                                                    
Out[100]: 
array([[[1, 1],
        [3, 3]],

       [[3, 2],
        [1, 1]],

       [[3, 2],
        [1, 3]]])

In [101]: B                                                                                                                                                    
Out[101]: array([2, 1, 3])

In [102]: np.power(A, B[:, np.newaxis, np.newaxis])                                                                                                            
Out[102]: 
array([[[ 1,  1],
        [ 9,  9]],

       [[ 3,  2],
        [ 1,  1]],

       [[27,  8],
        [ 1, 27]]])

np.newaxis的值为None,因此您经常会看到使用None而不是np.newaxis的表达式。您也可以使用**运算符代替函数power

In [103]: A ** B[:, None, None]                                                                                                                                
Out[103]: 
array([[[ 1,  1],
        [ 9,  9]],

       [[ 3,  2],
        [ 1,  1]],

       [[27,  8],
        [ 1, 27]]])