Numpy power ufunc, работающий на определенной оси

#python #numpy #numpy-ufunc

#python #numpy #numpy-ufunc

Вопрос:

Я нахожу странным, что numpy.power не имеет аргумента оси… это потому, что существует лучший / безопасный способ достижения той же цели (повышение каждого 2D-массива в 3D-массиве до уровня 1D-массива).

Предположим, у вас есть (3,10,10) массив (A), и вы хотите повысить каждый (10,10) массив до степени элементов в массиве B формы (3,). Вы должны быть в состоянии сделать это с помощью np.power(A,B,axis=0) , не так ли? Тем не менее, это приводит к следующему TypeError :

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

Поскольку кажется, что у power нет аргумента axis или axes (несмотря на то, что он ufunc), каков предпочтительный способ сделать это?

Может быть решение, использующее этот ufunc.reduce метод, но я не совсем понимаю, как это будет работать numpy.power

На данный момент я делаю :

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

Но это выглядит уродливо и, вероятно, менее эффективно, чем метод numpy.

Спасибо

Комментарии:

1. Вы могли бы использовать широковещательную передачу: A**B[:,None,None]

Ответ №1:

power это не операция сокращения: она не сводит набор чисел к одному числу, поэтому axis аргумент не имеет смысла. Такие операции, как sum или max , являются сокращениями, поэтому имеет смысл указать ось, вдоль которой будет применяться сокращение.

Операция, которую вы хотите, является широковещательной. Вот меньший пример, 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]]])