как размножение отличается для классов NumPy Matrix vs Array?

В документах numpy рекомендуется использовать массив вместо матрицы для работы с матрицами. Однако, в отличие от октавы (которую я использовал до недавнего времени), * не выполняет умножение матрицы, вам нужно использовать функцию matrixmultipy (). Я чувствую, что это делает код очень нечитаемым.

Кто-нибудь делится моими взглядами и нашел решение?

  • У Python есть решение для управления зависимостями версий?
  • Windows Scipy Install: не найдено ресурсов Lapack / Blas
  • Pandas не может читать файл hdf5, созданный с помощью h5py
  • конвертировать десятичную метку
  • python работает на бесконечном процессе
  • os.path.islink на windows с python
  • Разделите все элементы строкового списка
  • Как игнорировать предупреждения об отказе в Python
  • 7 Solutions collect form web for “как размножение отличается для классов NumPy Matrix vs Array?”

    Основная причина, почему следует избегать использования класса matrix состоит в том, что а) он по сути является двумерным, и б) есть дополнительные накладные расходы по сравнению с «нормальным» массивом numpy. Если все, что вы делаете, это линейная алгебра, то, во всяком случае, не стесняйтесь использовать матричный класс … Лично я считаю, что это больше проблем, чем того стоит.

    Для массивов (до Python 3.5) используйте dot вместо matrixmultiply .

    Например

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

    Или в новых версиях numpy просто используйте x.dot(y)

    Лично я считаю, что он гораздо читабельнее, чем оператор * подразумевающий матричное умножение …

    Для массивов в Python 3.5 используйте x @ y .

    ключевыми моментами, которые необходимо знать для операций с массивами NumPy и операциями с матрицами NumPy, являются:

    • Матрица NumPy является подклассом массива NumPy

    • Операции с массивами NumPy являются элементарными (когда учитывается широковещательная передача)

    • Операции матрицы NumPy следуют обычным правилам линейной алгебры

    некоторые фрагменты кода для иллюстрации:

     >>> from numpy import linalg as LA >>> import numpy as NP >>> a1 = NP.matrix("4 3 5; 6 7 8; 1 3 13; 7 21 9") >>> a1 matrix([[ 4, 3, 5], [ 6, 7, 8], [ 1, 3, 13], [ 7, 21, 9]]) >>> a2 = NP.matrix("7 8 15; 5 3 11; 7 4 9; 6 15 4") >>> a2 matrix([[ 7, 8, 15], [ 5, 3, 11], [ 7, 4, 9], [ 6, 15, 4]]) >>> a1.shape (4, 3) >>> a2.shape (4, 3) >>> a2t = a2.T >>> a2t.shape (3, 4) >>> a1 * a2t # same as NP.dot(a1, a2t) matrix([[127, 84, 85, 89], [218, 139, 142, 173], [226, 157, 136, 103], [352, 197, 214, 393]]) 

    но эти операции не выполняются, если эти две матрицы NumPy преобразуются в массивы:

     >>> a1 = NP.array(a1) >>> a2t = NP.array(a2t) >>> a1 * a2t Traceback (most recent call last): File "<pyshell#277>", line 1, in <module> a1 * a2t ValueError: operands could not be broadcast together with shapes (4,3) (3,4) 

    хотя использование синтаксиса NP.dot работает с массивами ; эта операция работает как матричное умножение:

     >> NP.dot(a1, a2t) array([[127, 84, 85, 89], [218, 139, 142, 173], [226, 157, 136, 103], [352, 197, 214, 393]]) 

    так вам нужна матрица NumPy? т. е. будет ли массив NumPy достаточным для вычисления линейной алгебры (если вы знаете правильный синтаксис, т. е. NP.dot)?

    правило, похоже, что если аргументы (массивы) имеют формы (mxn), совместимые с данной операцией линейной алгебры, то вы в порядке, иначе NumPy выбрасывает.

    единственное исключение, с которым я столкнулся (вероятнее всего, другие), вычисляет матрицу обратную .

    ниже – фрагменты, в которых я назвал операцию чистой линейной алгебры (фактически, из модуля линейной алгебры Numpy) и передан в массиве NumPy

    определитель массива:

     >>> m = NP.random.randint(0, 10, 16).reshape(4, 4) >>> m array([[6, 2, 5, 2], [8, 5, 1, 6], [5, 9, 7, 5], [0, 5, 6, 7]]) >>> type(m) <type 'numpy.ndarray'> >>> md = LA.det(m) >>> md 1772.9999999999995 

    собственные векторы / пары собственных значений :

     >>> LA.eig(m) (array([ 19.703+0.j , 0.097+4.198j, 0.097-4.198j, 5.103+0.j ]), array([[-0.374+0.j , -0.091+0.278j, -0.091-0.278j, -0.574+0.j ], [-0.446+0.j , 0.671+0.j , 0.671+0.j , -0.084+0.j ], [-0.654+0.j , -0.239-0.476j, -0.239+0.476j, -0.181+0.j ], [-0.484+0.j , -0.387+0.178j, -0.387-0.178j, 0.794+0.j ]])) 

    матричная норма :

     >>>> LA.norm(m) 22.0227 

    qr факторизация :

     >>> LA.qr(a1) (array([[ 0.5, 0.5, 0.5], [ 0.5, 0.5, -0.5], [ 0.5, -0.5, 0.5], [ 0.5, -0.5, -0.5]]), array([[ 6., 6., 6.], [ 0., 0., 0.], [ 0., 0., 0.]])) 

    матричный ранг :

     >>> m = NP.random.rand(40).reshape(8, 5) >>> m array([[ 0.545, 0.459, 0.601, 0.34 , 0.778], [ 0.799, 0.047, 0.699, 0.907, 0.381], [ 0.004, 0.136, 0.819, 0.647, 0.892], [ 0.062, 0.389, 0.183, 0.289, 0.809], [ 0.539, 0.213, 0.805, 0.61 , 0.677], [ 0.269, 0.071, 0.377, 0.25 , 0.692], [ 0.274, 0.206, 0.655, 0.062, 0.229], [ 0.397, 0.115, 0.083, 0.19 , 0.701]]) >>> LA.matrix_rank(m) 5 

    матричное условие :

     >>> a1 = NP.random.randint(1, 10, 12).reshape(4, 3) >>> LA.cond(a1) 5.7093446189400954 

    Для инверсии требуется матрица NumPy:

     >>> a1 = NP.matrix(a1) >>> type(a1) <class 'numpy.matrixlib.defmatrix.matrix'> >>> a1.I matrix([[ 0.028, 0.028, 0.028, 0.028], [ 0.028, 0.028, 0.028, 0.028], [ 0.028, 0.028, 0.028, 0.028]]) >>> a1 = NP.array(a1) >>> a1.I Traceback (most recent call last): File "<pyshell#230>", line 1, in <module> a1.I AttributeError: 'numpy.ndarray' object has no attribute 'I' 

    но псевдообращение Мура-Пенроуза, похоже, отлично работает

     >>> LA.pinv(m) matrix([[ 0.314, 0.407, -1.008, -0.553, 0.131, 0.373, 0.217, 0.785], [ 1.393, 0.084, -0.605, 1.777, -0.054, -1.658, 0.069, -1.203], [-0.042, -0.355, 0.494, -0.729, 0.292, 0.252, 1.079, -0.432], [-0.18 , 1.068, 0.396, 0.895, -0.003, -0.896, -1.115, -0.666], [-0.224, -0.479, 0.303, -0.079, -0.066, 0.872, -0.175, 0.901]]) >>> m = NP.array(m) >>> LA.pinv(m) array([[ 0.314, 0.407, -1.008, -0.553, 0.131, 0.373, 0.217, 0.785], [ 1.393, 0.084, -0.605, 1.777, -0.054, -1.658, 0.069, -1.203], [-0.042, -0.355, 0.494, -0.729, 0.292, 0.252, 1.079, -0.432], [-0.18 , 1.068, 0.396, 0.895, -0.003, -0.896, -1.115, -0.666], [-0.224, -0.479, 0.303, -0.079, -0.066, 0.872, -0.175, 0.901]]) 

    Существует ситуация, когда оператор точек будет давать разные ответы при работе с массивами, как при работе с матрицами. Например, предположим следующее:

     >>> a=numpy.array([1, 2, 3]) >>> b=numpy.array([1, 2, 3]) 

    Позволяет преобразовать их в матрицы:

     >>> am=numpy.mat(a) >>> bm=numpy.mat(b) 

    Теперь мы можем увидеть другой вывод для двух случаев:

     >>> print numpy.dot(aT, b) 14 >>> print am.T*bm [[1. 2. 3.] [2. 4. 6.] [3. 6. 9.]] 

    В 3.5, Python, наконец, получил матричный оператор умножения . Синтаксис – a @ b .

    Ссылка из http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html

    …, использование класса numpy.matrix не рекомендуется , поскольку оно не добавляет ничего, что не может быть выполнено с помощью 2D numpy.ndarray объектов, и может привести к путанице того, какой класс используется. Например,

     >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2],[3,4]]) >>> A array([[1, 2], [3, 4]]) >>> linalg.inv(A) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> b = np.array([[5,6]]) #2D array >>> b array([[5, 6]]) >>> bT array([[5], [6]]) >>> A*b #not matrix multiplication! array([[ 5, 12], [15, 24]]) >>> A.dot(bT) #matrix multiplication array([[17], [39]]) >>> b = np.array([5,6]) #1D array >>> b array([5, 6]) >>> bT #not matrix transpose! array([5, 6]) >>> A.dot(b) #does not matter for multiplication array([17, 39]) 

    Операции scipy.linalg могут быть одинаково применимы к numpy.matrix или к объектам 2D numpy.ndarray .

    Этот трюк может быть тем, что вы ищете. Это своего рода простая перегрузка оператора.

    Затем вы можете использовать что-то вроде предложенного класса Infix следующим образом:

     a = np.random.rand(3,4) b = np.random.rand(4,3) x = Infix(lambda x,y: np.dot(x,y)) c = a |x| b 

    Соответствующая цитата из PEP 465 – Специальный инфиксный оператор для умножения матриц , как упоминается @ petr-viktorin, разъясняет проблему, с которой сталкивается OP:

    […] numpy предоставляет два разных типа с различными методами __mul__ . Для объектов numpy.ndarray * выполняет элементное умножение, а умножение матрицы должно использовать вызов функции ( numpy.dot ). Для объектов numpy.matrix * выполняет умножение матрицы, а для элементарного умножения требуется синтаксис функции. Написание кода с помощью numpy.ndarray работает отлично. Написание кода с помощью numpy.matrix также отлично работает. Но проблема начинается, как только мы пытаемся объединить эти два фрагмента кода вместе. Код, который ожидает ndarray и получает matrix , или наоборот, может привести к сбою или возврату неверных результатов

    Введение оператора @ infix должно помочь унифицировать и упростить код матрицы python.

    Python - лучший язык программирования в мире.