Сначала давайте придирчивы к обозначениям.
a = [[1] [2] [3]]
не является допустимым Python. Вы получите синтаксическую ошибку, даже если ваша цель - пустой массив.
In [202]: a = np.array([[1],[2],[3]])
In [203]: a.shape
Out[203]: (3, 1)
In [204]: a
Out[204]:
array([[1],
[2],
[3]])
In [205]: print(a)
[[1]
[2]
[3]]
При выводе на экран print / str массива пропускаются запятые, но скобки являются неотъемлемой частью дисплея. Они помогают показать размеры массива. Эквивалент этого массива в списке отображается как [[1], [2], [3]]
.
Если я сделаю dot
из (1,3) с (3,1), результат будет (1,1). dot
(и ваша inner
версия сохраняют внешние размеры массивов.
In [206]: np.dot(a.T,a)
Out[206]: array([[14]])
In [207]: _.shape
Out[207]: (1, 1)
Мы можем «сгладить» массив, поэтому его форма теперь (3,):
In [209]: a1 = a.ravel()
In [210]: a1
Out[210]: array([1, 2, 3])
In [211]: np.dot(a1,a1)
Out[211]: 14
np.dot
имеет специальную документированную обработку для аргументов 1d массива. Обратите внимание, что транспонирование .T
не требуется. Транспозиция ничего не делает для формирования 1d массива.
np.inner
также работает, но np.dot
используется чаще:
In [215]: np.inner(a.T, a.T)
Out[215]: array([[14]])
In [216]: np.inner(a1, a1)
Out[216]: 14
И в последние годы есть функция matmul
и оператор @
, которые работают аналогично:
In [217]: a.T@a
Out[217]: array([[14]])
Размеры можно удалить после расчета:
In [218]: (a.T@a).squeeze()
Out[218]: array(14)
In [219]: (a.T@a).item()
Out[219]: 14