Факториал матрицы поэлементно с Numpy

Я хотел бы знать, как вычислить факториал матрицы поэлементно. Например,

import numpy as np
mat = np.array([[1,2,3],[2,3,4]])

np.the_function_i_want(mat)

даст матрицу mat2 такую, что mat2[i,j] = mat[i,j]!. Я пробовал что-то вроде

np.fromfunction(lambda i,j: np.math.factorial(mat[i,j]))

но он передает всю матрицу в качестве аргумента для np.math.factorial. Я также пытался использовать scipy.vectorize, но для матриц больше 10x10 я получаю сообщение об ошибке. Это код, который я написал:

import scipy as sp
javi = sp.fromfunction(lambda i,j: i+j, (15,15))
fact = sp.vectorize(sp.math.factorial)
fact(javi)

OverflowError: Python int too large to convert to C long

Такое целое число было бы больше 2e9, поэтому я не понимаю, что это значит.


person Javier Garcia    schedule 16.06.2015    source источник


Ответы (1)


В scipy.misc, который позволяет выполнять поэлементные вычисления с массивами:

>>> from scipy.misc import factorial
>>> factorial(mat)
array([[  1.,   2.,   6.],
       [  2.,   6.,  24.]])

Функция возвращает массив значений с плавающей запятой и, таким образом, может вычислять «более крупные» факториалы с точностью, допускаемой числами с плавающей запятой:

>>> factorial(15)
array(1307674368000.0)

Вам может потребоваться настроить точность печати массивов NumPy, если вы хотите избежать отображения числа в экспоненциальном представлении.


Что касается scipy.vectorize: OverflowError означает, что результат некоторых вычислений слишком велик для хранения в виде целых чисел (обычно int32 или int64).

Если вы хотите векторизовать sp.math.factorial и хотите произвольно большие целые числа, вам нужно указать, что функция возвращает выходной массив с типом данных 'object'. Например:

fact = sp.vectorize(sp.math.factorial, otypes='O')

Указание типа 'object' позволяет возвращать целые числа Python с помощью fact. Они не ограничены по размеру, поэтому вы можете вычислять факториалы настолько больших размеров, насколько позволяет память вашего компьютера. Имейте в виду, что массивы этого типа теряют некоторые преимущества в скорости и эффективности, которыми обладают обычные массивы NumPy.

person Alex Riley    schedule 16.06.2015
comment
Спасибо за вашу помощь! Это было очень полезно. - person Javier Garcia; 17.06.2015
comment
@JavierGarcia: Нет проблем! Я рад, что смог помочь. - person Alex Riley; 17.06.2015
comment
Для scipy ›= 1.0.0 factorial из scipy.misc устарело. Вместо этого нужно использовать scipy.special.factorial. - person Genius; 15.12.2018