Как NumPy определяет размеры вектора столбца? - PullRequest
1 голос
/ 20 октября 2019

Я начал с numpy и пытался выяснить, как его массивы работают для векторов столбцов. Определяя следующее:

x1 = np.array([3.0, 2.0, 1.0])
x2 = np.array([-2.0, 1.0, 0.0])

И вызывая

print("inner product x1/x2: ", np.inner(x1, x2))

Создает inner product x1/x2: -4.0, как и ожидалось - это заставило меня думать, что numpy предполагает, что массив этой формы является вектором столбца и, какчасть внутренней функции, транспонирует один из них, чтобы дать скаляр. Однако я написал некоторый код для проверки этой идеи, и он дал некоторые результаты, которые я не понимаю.

После некоторого поиска в Google, как указать, что массив является вектором столбца, используя .T, я определилследующее:

x = np.array([1, 0]).T
xT = np.array([1, 0])

Где я хотел, чтобы x был вектором столбца, а xT - вектором строки. Однако, вызывая следующее:

print(x)
print(x.shape)

print(xT)
print(xT.shape)

Производит это:

[1 0]
(2,)
[1 0]
(2,)

Что предполагает, что два массива имеют одинаковые размеры, несмотря на то, что один является транспонированным для другого. Более того, вызов np.inner(x,x) и np.inner(x,xT) дает одинаковый результат. Я неправильно понимаю функцию .T, или, может быть, какая-то фундаментальная особенность NumPy / линейной алгебры? Я не думаю, что x & xT должен быть одним и тем же вектором.

Наконец, изначально я использовал .T, потому что попытка определить вектор столбца как x = np.array([[1], [0]]) и вызов print(np.inner(x, x)) произвелиследующий как внутренний продукт:

[[1 0]
 [0 0]]

Какой результат вы ожидаете увидеть для внешнего продукта. Я неправильно использую этот способ определения вектора столбца?

1 Ответ

0 голосов
/ 20 октября 2019

Посмотрите на inner документы:

Ordinary inner product of vectors for 1-D arrays 
...
np.inner(a, b) = sum(a[:]*b[:])

С вашими массивами образцов:

In [374]: x1 = np.array([3.0, 2.0, 1.0]) 
     ...: x2 = np.array([-2.0, 1.0, 0.0])                                       
In [375]: x1*x2                                                                 
Out[375]: array([-6.,  2.,  0.])
In [376]: np.sum(x1*x2)                                                         
Out[376]: -4.0
In [377]: np.inner(x1,x2)                                                       
Out[377]: -4.0
In [378]: np.dot(x1,x2)                                                         
Out[378]: -4.0
In [379]: x1@x2                                                                 
Out[379]: -4.0

Из вики для dot/scalar/inner product:

https://en.wikipedia.org/wiki/Dot_product

two equal-length sequences of numbers (usually coordinate vectors) and returns a single number

enter image description here

If vectors are identified with row matrices, the dot product can also 
be written as a matrix product

Исходя из мира линейной алгебры, легко представить все в терминах матриц (2d) и векторов, которые представляют собой 1 строку или 1 столбец матрицы. MATLAB / Octave работает в этом контексте. Но numpy является более общим, с массивами с 0 или более измерениями, а не только с 2.

np.transpose не добавляет измерения, а просто переставляет существующие. Следовательно, x1.T ничего не меняет.

Вектор столбца можно сделать с помощью np.array([[1], [0]]) или:

In [381]: x1                                                                    
Out[381]: array([3., 2., 1.])
In [382]: x1[:,None]                                                            
Out[382]: 
array([[3.],
       [2.],
       [1.]])
In [383]: x1.reshape(3,1)                                                       
Out[383]: 
array([[3.],
       [2.],
       [1.]])

np.inner описывает, что происходит, когда входы не 1d, например,Ваша 2d (2,1) форма x. Он говорит, что использует np.tensordot, который является обобщением np.dot, матричного произведения.

In [386]: x = np.array([[1],[0]])                                               
In [387]: x                                                                     
Out[387]: 
array([[1],
       [0]])
In [388]: np.inner(x,x)                                                         
Out[388]: 
array([[1, 0],
       [0, 0]])
In [389]: np.dot(x,x.T)                                                         
Out[389]: 
array([[1, 0],
       [0, 0]])
In [390]: x*x.T                                                                 
Out[390]: 
array([[1, 0],
       [0, 0]])

Это поэлементное произведение (2,1) и (1,2), приводящее к (2, 2), или внешнее произведение.

...