проблема с объединенными массивами - PullRequest
0 голосов
/ 13 декабря 2018

Я портирую некоторый код Matlab на python, и у меня есть следующее утверждение в Matlab:

cross([pt1,1]-[pp,0],[pt2,1]-[pp,0]);

pt1, pt2 и pp являются точками 2D.

Итак, мой соответствующий код Python выглядит следующим образом:

np.cross(np.c_[pt1 - pp, 1], np.c_[pt2 - pp, 1])

Точки определены как:

pt1  = np.asarray((440.0, 59.0))
pt2 = np.asarray((-2546.23, 591.03))
pp = np.asarray([563.,  456.5])

Когда я выполняю инструкцию с перекрестным произведением, я получаю следующую ошибку:

ValueError: all the input array dimensions except for the concatenation axis must match exactly

Итак, просматривая некоторые другие сообщения, я подумал, что попробую np.column_stack, но получаю ту же ошибку:

np.cross(np.column_stack((pt1 - pp, 1)), np.column_stack((pt2 - pp, 1)))

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Если вы используете np.r_, вместо этого он работает:

In [40]: np.cross(np.r_[pt1 - pp, 1], np.r_[pt2 - pp, 1])
Out[40]: array([-5.32030000e+02, -2.98623000e+03, -1.25246611e+06])

Ваши pt1 и pp являются (2,) массивами.Чтобы добавить к ним 1, вам нужно использовать 1d сцепление, np.r_ для 'row', в отличие от columns.

Существует множество способов построения массива из 3 элементов:

In [43]: np.r_[pt1 - pp, 1]
Out[43]: array([-123. , -397.5,    1. ])
In [44]: np.append(pt1 - pp, 1)
Out[44]: array([-123. , -397.5,    1. ])
In [45]: np.concatenate((pt1 - pp, [1]))
Out[45]: array([-123. , -397.5,    1. ])

concatenate - базовая операция.Другие настраивают 1, чтобы создать массив 1d, который можно объединить с массивом формы (2,), чтобы сделать (3,).

Конкатенация превращает все свои входные данные в массивы, если они неуже: np.concatenate((pt1 - pp, np.array([1]))).

Обратите внимание, что np.c_ документы говорят, что это эквивалент

np.r_['-1,2,0', index expression]

Это начальное строковое выражение немного сложнее.Ключевым моментом является то, что он пытается объединить 2d массивы (тогда как ваш pt1 равен 1d).

Это похоже на column_stack, joining n (2,1) arrays to make a (2, n) `массив.

In [48]: np.c_[pt1, pt2]
Out[48]: 
array([[  440.  , -2546.23],
       [   59.  ,   591.03]])
In [50]: np.column_stack((pt1, pt2))
Out[50]: 
array([[  440.  , -2546.23],
       [   59.  ,   591.03]])

В MATLAB все имеет по крайней мере 2 измерения, и поскольку он основан на Fortran, внешние измерения являются последними.Таким образом, в некотором смысле его наиболее естественная «векторная» форма - это nx 1, матрица столбцов.numpy построен на Python, с естественным интерфейсом к его скалярам и вложенным спискам.Заказ основан на c;начальные размеры самые внешние.Таким образом, код numpy может иметь истинные скаляры (числа Python без формы или размера) или массивы с 0 или более измерениями.«Вектор» наиболее естественно имеет форму (n,) (набор из 1 элемента).При необходимости его можно легко изменить на (1, n) или (n, 1).

Если вам нужен массив (3,1) (вместо (3,)), вам нужно использовать некую «вертикальную» конкатенацию, соединяя массив (2,1) с(1,1):

In [51]: np.r_['0,2,0', pt1-pp, 1]
Out[51]: 
array([[-123. ],
       [-397.5],
       [   1. ]])
In [53]: np.vstack([(pt1-pp)[:,None], 1])
Out[53]: 
array([[-123. ],
       [-397.5],
       [   1. ]])

(Но np.cross хочет (n, 3) или (3,) массивы, а не (3,1)!)

In [58]: np.cross(np.r_['0,2,0', pt1-pp, 1], np.r_['0,2,0', pt2-pp, 1])
...
ValueError: incompatible dimensions for cross product
(dimension must be 2 or 3)

Чтобы обойти это, укажите ось:

In [59]: np.cross(np.r_['0,2,0', pt1-pp, 1], np.r_['0,2,0', pt2-pp, 1], axis=0)
Out[59]: 
array([[-5.32030000e+02],
       [-2.98623000e+03],
       [-1.25246611e+06]])

Изучите np.cross, если вы хотите пример манипулирования размерами.В этом axis=0 случае он транспонирует массивы, чтобы они были (1,3), а затем выполняет расчет.

0 голосов
/ 13 декабря 2018

Это может быть то, что вы ищете:

np.cross(np.append(pt1-pp, 1), np.append(pt2-pp, 1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...