NumPy Power Ufunc работает на определенной оси - PullRequest
3 голосов
/ 18 апреля 2019

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

Предположим, у вас есть (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 не имеет аргумента оси или оси (несмотря на то, что он является уфункцией), какой способ предпочтительнее сделать?

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

Пока я делаю:

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

Но это выглядит некрасиво и, вероятно, менее эффективно, чем простой метод.

Спасибо

1 Ответ

4 голосов
/ 18 апреля 2019

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, поэтому вы часто будете видеть выражения, которые вместо этого используют Nonenp.newaxis.Вы также можете использовать оператор ** вместо функции power:

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

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

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