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

#python #arrays #numpy #factorial

#python #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 , но для матриц размером более 10×10 я получаю сообщение об ошибке. Это код, который я написал:

 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, поэтому я не понимаю, что это значит.

Ответ №1:

Есть factorial функция, scipy.special которая позволяет поэлементно вычислять массивы:

 >>> from scipy.special 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.

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

1. Спасибо за вашу помощь! Это было очень полезно.

2. @JavierGarcia: Нет проблем! Я рад, что смог помочь.

3. Для scipy > = 1.0.0 factorial from scipy.misc устарел. Вместо этого нужно использовать scipy.special.factorial .