Как поднять массив numpy до мощности? (соответствует повторяющимся матричным умножениям, а не поэлементно)

Я хочу поднять двумерный numpy array, назовем его A, в степень некоторого числа n, но до сих пор мне не удалось найти функцию или оператор для этого.

Я знаю, что могу привести его к типу matrix и использовать тот факт, что тогда (аналогично поведению в Matlab) A**n делает именно то, что я хочу (для array одно и то же выражение означает поэлементное возведение в степень). Однако приведение к matrix и обратно кажется довольно уродливым обходным путем.

Наверняка должен быть хороший способ выполнить это вычисление, сохранив формат array?


person mirari    schedule 16.02.2011    source источник
comment
Хотя это возможно, как указал Джо Кингстон, обратите внимание, что массивы и матрицы принципиально разные. array — это числовой набор элементов в многомерном пространстве, где matrix — это абстрактный объект (представленный двумерным массивом) — такая же разница, как между вектором и одномерным массивом. (Для инвентаря фруктов имеет смысл быть массивом [1,2,3], представляющим 1 яблоко, 2 апельсина, 3 банана, но не имеет смысла для вектора - яблоки нельзя складывать/умножать/преобразовывать в апельсины) . Таким образом, массивы имеют поэлементные операции, а матрицы — умножение матриц, det() и т. д.   -  person dr jimbob    schedule 16.02.2011
comment
Если вам нравится ответ Джо, вы должны проверить его как принятый, чтобы отдать должное Джо и сообщить другим, что этот вопрос решен.   -  person Sven Marnach    schedule 17.02.2011


Ответы (2)


Я полагаю, вы хотите numpy.linalg.matrix_power

В качестве быстрого примера:

import numpy as np
x = np.arange(9).reshape(3,3)
y = np.matrix(x)

a = y**3
b = np.linalg.matrix_power(x, 3)

print a
print b
assert np.all(a==b)

Это дает:

In [19]: a
Out[19]: 
matrix([[ 180,  234,  288],
        [ 558,  720,  882],
        [ 936, 1206, 1476]])

In [20]: b
Out[20]: 
array([[ 180,  234,  288],
       [ 558,  720,  882],
       [ 936, 1206, 1476]])
person Joe Kington    schedule 16.02.2011
comment
Да, это именно то, что мне было нужно. Благодарю вас! - person mirari; 17.02.2011
comment
Я чувствую себя несколько застенчивым из-за того, что не додумался посмотреть явно в модуль linalg, но отдельное спасибо за указание на то, что это место также. Хороший быстрый пример; очень показательно. - person mirari; 17.02.2011

Функция opencv cvPow кажется примерно в 3-4 раза быстрее на моем компьютере при повышении до рационального числа. Вот пример функции (у вас должен быть установлен модуль pyopencv):

import pyopencv as pycv
import numpy
def pycv_power(arr, exponent):
    """Raise the elements of a floating point matrix to a power. 
    It is 3-4 times faster than numpy's built-in power function/operator."""
    if arr.dtype not in [numpy.float32, numpy.float64]:
        arr = arr.astype('f')
    res = numpy.empty_like(arr)
    if arr.flags['C_CONTIGUOUS'] == False:
        arr = numpy.ascontiguousarray(arr)        
    pycv.pow(pycv.asMat(arr), float(exponent), pycv.asMat(res))
    return res   
person Lennart Liberg    schedule 30.03.2011