Numpy скалярное произведение матрицы и массива является матрицей

Когда я обновился до самой последней версии numpy, большая часть моего кода сломалась, потому что теперь каждый раз, когда я вызываю np.dot() для матрицы и массива, он возвращает матрицу 1xn, а не просто массив. Это вызывает у меня ошибку, когда я пытаюсь умножить новый вектор/массив на матрицу

пример

A = np.matrix( [ [4, 1, 0, 0], [1, 5, 1, 0], [0, 1, 6, 1], [1, 0, 1, 4] ] )

x = np.array([0, 0, 0, 0])
print(x)

x1 = np.dot(A, x)
print(x1)

x2 = np.dot(A, x1)
print(x2)

output:
[0 0 0 0]
[[0 0 0 0]]
Traceback (most recent call last):
  File "review.py", line 13, in <module>
    x2 = np.dot(A, x1)
ValueError: shapes (4,4) and (1,4) not aligned: 4 (dim 1) != 1 (dim 0)

Я ожидаю, что либо точка матрицы и вектора вернет вектор, либо точка матрицы и матрица 1xn будут работать, как ожидалось.

Использование транспонирования x не исправляет это, равно как и использование A @ x, A.dot(x) или любого другого варианта np.matmul(A, x).

Как бы это ни раздражало, это может быть хорошим моментом для избавиться от matrix навсегда.

Paul Panzer 22.05.2019 04:43
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
1
1
190
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваши массивы:

In [24]: A = np.matrix( [ [4, 1, 0, 0], [1, 5, 1, 0], [0, 1, 6, 1], [1, 0, 1, 4] ] )   
    ...: x = np.array([0, 0, 0, 0])                                                                      
In [25]: A.shape                                                                                         
Out[25]: (4, 4)
In [26]: x.shape                                                                                         
Out[26]: (4,)

Точка:

In [27]: np.dot(A,x)                                                                                     
Out[27]: matrix([[0, 0, 0, 0]])     # (1,4) shape

Давайте попробуем то же самое, но с ndarray версией A:

In [30]: A.A                                                                                             
Out[30]: 
array([[4, 1, 0, 0],
       [1, 5, 1, 0],
       [0, 1, 6, 1],
       [1, 0, 1, 4]])
In [31]: np.dot(A.A, x)                                                                                  
Out[31]: array([0, 0, 0, 0])

Результатом является (4,) форма. Это имеет смысл: (4,4) точка (4,) => (4,)

np.dot(A,x) выполняет те же вычисления, но возвращает np.matrix. Это по определению двумерный массив, поэтому (4,) расширяется до (1,4).

У меня нет более старой версии, чтобы проверить это, и я не знаю о каких-либо изменениях.

Если x является матрицей (4,1), то результат (4,4)dot(4,1)=>(4,1):

In [33]: np.matrix(x)                                                                                    
Out[33]: matrix([[0, 0, 0, 0]])
In [34]: np.dot(A, np.matrix(x).T)                                                                       
Out[34]: 
matrix([[0],
        [0],
        [0],
        [0]])

Спасибо за быстрый ответ! Ваше решение работает. Кажется непоследовательным иметь возможность расставить точки над матрицей по вектору-строке, если это массив, но не если это матрица. Я просто буду использовать класс np.array вместо np.matrix.

Jackson 22.05.2019 04:53

Ваш x с формой (4,) представляет собой массив 1d. Вы можете думать об этом как о векторе или векторе-строке, но это не меняет размеры или форму. np.dot описывает, как он обрабатывает массивы 1d, независимо от того, являются ли они первыми или вторыми. У некоторых людей (с опытом работы в MATLAB или линейной алгебре) возникают проблемы с представлением одномерного массива, который не является ни строкой, ни вектором-столбцом.

hpaulj 22.05.2019 05:09

Другие вопросы по теме