Например, я хочу векторизовать функцию, возвращающую определитель матрицы.
Поэтому я пробую следующие коды:
data1test=np.random.rand(2,2)
data2test=np.random.rand(2,2)
data3test=np.random.rand(2,2)
data4test=np.random.rand(2,2)
fulldata=np.array((data1test,data2test,data3test,data4test))
def det_vec():
return np.vectorize(np.linalg.det)
myfunc=det_vec()
myfunc(fulldata)
Однако он возвращает ошибку «LinAlgError: задан 0-мерный массив. Массив должен быть как минимум двумерным».
Может ли кто-нибудь показать мне, в чем проблема? Спасибо!
Что указано в документах det
? Ввод (..., M, M) array_like
означает, что он принимает многомерный массив, последние два измерения которого одинаковы. И возвращает результат (...)
, то есть det каждого подмассива (M,M). Что такое fulldata.shape
?
Не используйте np.vectorize
, не прочитав (и не попытавшись понять) его документацию. Обратите внимание на то, что он на самом деле говорит, а не на то, что вы хотели бы. vectorize
передает скалярные значения в вашу функцию — если вы не укажете signature
, что медленнее. Это не инструмент «производительности».
Казалось бы, ваша векторизованная функция векторизуется слишком глубоко.
Вы можете использовать аргумент signature
, чтобы обойти это и принудительно векторизировать только на верхнем уровне:
>>> myfunc = np.vectorize(np.linalg.det, signature = "(a,b,c)->(a)")
>>> myfunc((np.eye(2), np.array([[1,3],[4,2]])))
array([ 1., -10.])
Обновлено: стоит отметить, что @hpaulj прав - здесь даже не обязательно явная векторизация. См. следующее:
>>> np.linalg.det((np.eye(2), np.array([[1,3],[4,2]])))
array([ 1., -10.])
Если я не ошибаюсь, происходит то, что
numpy
пытается взять определитель каждого отдельного элемента в каждом из ваших массивов, а не просто сопоставляет функцию с каждым тестовым массивом. Что-то вроде stackoverflow.com/questions/67359587/… может быть актуально.