как мне взять скалярное произведение этих двух массивов разной формы?

#python #numpy

#python #numpy

Вопрос:

  xT_dot_x_dot_xT = [[ 0.00000000e 00 -5.06371260e-04 -1.97580457e-03]
 [ 0.00000000e 00 -7.54147768e-04  1.70472264e-03]
 [ 0.00000000e 00  4.02927399e-05  3.20196152e-04]
 [ 0.00000000e 00  8.85248184e-04 -2.95877457e-04]
 [ 0.00000000e 00  2.01046467e-04  2.06828117e-05]
 [ 0.00000000e 00  5.04493713e-04  5.10215759e-04]
 [ 0.00000000e 00  8.46385956e-05 -8.65459442e-05]
 [ 0.00000000e 00  6.81161880e-04 -5.64813614e-04]
 [ 0.00000000e 00 -6.24537468e-04  3.47018242e-04]
 [ 0.00000000e 00 -3.38315964e-04  2.02894211e-04]] 
 y = [[208500]
 [181500]
 [223500]
 [140000]
 [250000]
 [143000]
 [307000]
 [200000]
 [129900]
 [118000]]
  

эти данные были получены примерно таким образом:

 print(x, y)
[[1710 2003]
 [1262 1976]
 [1786 2001]
 [1717 1915]
 [2198 2000]
 [1362 1993]
 [1694 2004]
 [2090 1973]
 [1774 1931]
 [1077 1939]] [[208500]
   [181500]
   [223500]
   [140000]
   [250000]
   [143000]
   [307000]
   [200000]
   [129900]
   [118000]]
zeros = np.zeros((len(x), 1))
x = np.append(zeros, x, axis=1)

#print("values for processn", x,y)

xT = np.transpose(np.linalg.inv(np.tensordot(x.T, x, axes=([0],[-1]))))
xx = np.tensordot(xT, x.T, axes=([0],[-1]))
print("intermediaten", xx, y)
# wls = np.tensordot(xx, y, axes=([-1],[0])) # -- failing line
  

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

Комментарии:

1. Вы этого не делаете: скалярное произведение определено для двух векторов одинаковой длины. Пожалуйста, уточните, что вы собираетесь получить в результате.

2. @Prune Я предполагаю, что я сделал это неправильно — что означает равная длина? Они оба имеют длину 10 строк.

3. документ

4. Я так понимаю, что вам нужно скалярное произведение y для каждого столбца x ? Это не так tensordot работает. Оба массива должны иметь одинаковое количество измерений, и вам нужно правильно указать оси. Смотрите примеры.

5. хорошо, итак, я должен .. возможно, с самого начала разделить x на 3 отдельных массива и сделать это с каждым отдельно. @Prune спасибо.

Ответ №1:

Входные массивы (также известные как векторы или матрицы) должны иметь одинаковые размеры, а не одинаковую длину. Например, следующее будет работать нормально:

 xa = np.array([[2,3,4,5], [1,2,4,3], [2,3,2]])
ya = np.array([[1], [2], [9]])
np.dot(xa, ya)
  

Возможно, вы захотите изучить, зачем вам нужно скалярное произведение — в зависимости от того, как вы интерпретируете данные, вам, вероятно, потребуется добавить два измерения к вашему массиву «y», заполненному единицами. Предполагая, что значения расположены вдоль оси y, это может быть дополнено следующим образом:

  y = [[1, 208500, 1],
 [1, 181500, 1]] #and so on for the remaining rows
  

Опять же, вам просто нужно убедиться, к какой оси принадлежат ваши значения.

Комментарии:

1. однако при использовании tensordot они не обязательно должны иметь одинаковую форму

Ответ №2:

Итак, ваш x равен (10,2) и y равен (10,1):

Tensordot выдает (10,10) и совпадает с switched dot (матричное произведение):

 np.tensordot(x.T,x, axes=[[0],[-1]])
np.dot(x,x.T) 
x@x.T
np.einsum('ij,kj',x,x)
  

То есть суммирование происходит в меньшем измерении размером 2.

xT и xx также (10,10)

 np.tensordot(xx,y, axes=[[-1],[0]])
np.dot(x1,y)
  

выдает (10,1), объединив a (10,10) с (10,1) по последней и со 2-й по последнюю оси.


Упс, я пропустил:

 x = np.append(np.zeros((10,1),int),x, axis=1) 
  

что создает массив (10,3). Но tensordot с x.T все еще суммирует в меньшем измерении, производя (10,10).


Упс, дальнейшее исправление, я пропустил деталь в xx calc.

  xT (10,10)
 xx (10,10) with (10,3) => (10,3)
  

Теперь

 np.tensordot(xx,y, axes=[[-1],[0]])
  

проблематично, потому что оно стремится объединить (10,3) и (10,1) в измерениях 3 и 10.

 np.dot(xx,y)
ValueError: shapes (10,3) and (10,1) not aligned: 3 (dim 1) != 10 (dim 0)
  

Вы могли бы просуммировать две цифры 10, создав массив (3,1). Это то, чего вы хотите?

 np.dot(x.T,y)     # (3,10) with (10,1) => (3,1)
  

Комментарии:

1. это. Прошу прощения, я думал , что мне нужен массив (10,1), но мне нужен массив (3,1) .. ваш ответ отражает то, что я уже реализовал самостоятельно. Спасибо