2016-06-29 2 views
-1

У меня есть несколько переменных, перечисленных ниже. Почему я получаю сообщение об ошибке внизу, когда пытаюсь запустить этот блок кода? Ind_var[i,:] должен иметь форму (1,2), так что матричным умножением (1,2) * (2,2) является (1,2)? Извините, я новичок в python. сообщениеНесоответствие размера Python для умножения

import numpy as np 

spread_len = 10 
n_param = 2 
Q = np.zeros((spread_len,1)) 
ind_var = np.zeros((spread_len,2)) 
R = np.zeros((n_param,n_param)) 
Ve = 0.001 

for i in range(spread_len): 
    Q[i]=ind_var[i,:]*R*ind_var[i,:]+Ve 

Ошибка:

ValueError: could not broadcast input array from shape (2,2) into shape (1)

+0

Возможно, вы сбиваете с толку '*' с матричным умножением в MATLAB, в отличие от NumPy, который идет как элементное умножение? – Divakar

ответ

0

Вам нужно перенести второй ind_var [я ,:], чтобы получить (2,1) форму, в противном случае вы охватывает новый (2,2), которая не вписывается в Q [i], которая является формой (1).

Также R и ind_var должны быть матрицами, а не массивы, для матрицы математике:

import numpy as np 

spread_len = 10 
n_param = 2 
Q = np.zeros((spread_len,1)) 
ind_var = np.asmatrix(np.zeros((spread_len,2))) 
R = np.asmatrix(np.zeros((n_param,n_param))) 
Ve = 0.001 

for i in range(spread_len): 
    Q[i]=ind_var[i,:]*R*ind_var[i,:].T+Ve 

Может быть, не красивое решение, но вы можете перейти от здесь и использовать matlib для создания матриц.

import numpy as np 
import numpy.matlib as ml 

spread_len = 10 
n_param = 2 
Q = np.zeros((spread_len,1)) 
ind_var = ml.zeros((spread_len,2)) 
R = ml.zeros((n_param,n_param)) 
Ve = 0.001 

for i in range(spread_len): 
    Q[i]=ind_var[i,:]*R*ind_var[i,:].T+Ve 
+0

Итак, я попробовал 'np.transpose' второй' ind_var [i,:] ', как' Q [i] = ind_var [i,:] * R * np.transpose (ind_var [i,:]) + Ve' но я все равно получаю такое же сообщение об ошибке ** ValueError: не удалось передать входной массив из формы (2,2) в форму (1) ** – A1122

+0

Вы можете напрямую использовать 'np.matrix', не импортируя модуль' ml'. – hpaulj

0

В вашем примере:

In [970]: ind_var.shape 
Out[970]: (10, 2) 

In [971]: R.shape 
Out[971]: (2, 2) 

In [972]: ind_var[0,:]*R*ind_var[0,:]+Ve 
Out[972]: 
array([[ 0.001, 0.001], 
     [ 0.001, 0.001]]) 

Для массивов, то * умножение поэлементно, как MATLAB .*. Таким образом, получается форма R, а неправильный размер - в ячейке Q.

Существует множество умножение матриц, np.dot:

In [973]: np.dot(ind_var[0,:], np.dot(R, ind_var[0,:]))+Ve 
Out[973]: 0.001 

Существует подкласс массива, np.matrix, который вынужден быть 2d (как старый MATLAB) и использует * для матричного произведения

In [981]: Rm=np.matrix(R) 
In [982]: ind_m=np.matrix(ind_var) 
In [983]: ind_m[0,:]*R*ind_m[0,:].T+Ve 
Out[983]: matrix([[ 0.001]]) 

np.einsum является обобщением np.dot, который может выполнять все вычисления за один шаг

In [985]: np.einsum('ij,jk,ik->i', ind_var, R, ind_var)+Ve 
Out[985]: 
array([ 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 
     0.001, 0.001]) 

R и ind_var В этом примере все значения равны 0, поэтому результаты не являются диагностическими - кроме формы.

Я собирался предложить нового оператора matmul, @, но [email protected]@ind_var.T производит массив 10x10, который мы не хотим. Итеративный ind_var[0,:]@[email protected]_var[0,:] в порядке.

(Я действительно должен проверять вещи с нетривиальными значениями).

Смежные вопросы