Ошибка NumPy о том, что матрицы не выровнены - PullRequest
0 голосов
/ 07 июня 2019

Если я бегу:

x = np.zeros(6)
y = np.zeros([7, 6])
z = y * x

Тогда все в порядке, и ошибок Python нет.

Однако я использую модуль Python (call if foo), содержащий функцию (call if bar), которая возвращает массив NumPy 7x6. Он имеет ту же форму, что и y выше, и тот же тип данных (float64). Но когда я запускаю следующее:

x = np.zeros(6)
y = foo.bar()
z = y * x

Я получаю следующую ошибку:

ValueError: shapes (7,6) and (1,6) not aligned: 6 (dim 1) != 1 (dim 0)

Но, насколько я могу судить, y - это абсолютно одинаковый формат в этих двух примерах с одинаковой формой и типом данных. Что вызывает эту ошибку, и почему она не вызывается в первом примере?

Ответы [ 2 ]

1 голос
/ 08 июня 2019
In [446]: x = np.zeros(6) 
     ...: y = np.zeros([7, 6]) 
     ...: z = y * x                                                                                    
In [447]: z.shape                                                                                      
Out[447]: (7, 6)

Здесь мы делаем поэлементное умножение, (7,6) с (6,). Передавая (6,) становится (1,6), а затем (7,6), чтобы соответствовать y.

Очевидно, в случае foo.bar, y - это np.matrix подкласс:

In [454]: y1 = np.matrix(y)                                                                            
In [455]: y1*x                                                                                         
---...
    219             # This promotes 1-D vectors to row vectors
--> 220             return N.dot(self, asmatrix(other))
...
ValueError: shapes (7,6) and (1,6) not aligned: 6 (dim 1) != 1 (dim 0)

Обратите внимание на другой дисплей для y1:

In [456]: y1                                                                                           
Out[456]: 
matrix([[0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.]])

С np.matrix * определяется как np.dot, матричное произведение. x также конвертируется np.matrix, создавая матрицу (1,6). Сообщение об ошибке следует из определения умножения матриц.

np.multiply может использоваться для поэлементного умножения. Обратите внимание на класс результата:

In [458]: np.multiply(y1,x)                                                                            
Out[458]: 
matrix([[0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0.]])

Из-за подобных заблуждений np.matrix не поощряется.

1 голос
/ 07 июня 2019

Я не знаю, какую версию вы используете, но я использую версию 1.16.3 на Python 3.

Мне кажется, вы определяете свой x иначе, чем в своем примере фрагмента. Похоже, вы определяете ее как матрицу 6x1 вместо «вектора», который, как считается, в Numpy имеет только одно измерение. Попробуйте умножить y на np.zeros([6,1]), и вы увидите ошибку.

Итог:

  1. Часто используйте свойство .shape при отладке, это очень полезно при умножении матриц.
  2. В np умножение между матрицей и одномерным массивом переносится иначе, чем умножение между двумя матрицами.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...