вопрос numpy reshape (сравнение matlab)

#matlab #numpy #reshape

#matlab #numpy #изменение формы

Вопрос:

Допустим, у меня есть одномерный вектор с именем s, состоящий из 0,3,6,9.

В MATLAB форма обозначается (1,4). т. е. вектор-строка размером 1×4.

Но в numpy форма задается как (4,). Почему? Разве это обозначение не должно обозначать вектор 4×1, поскольку python также использует соглашение row x col?

Теперь, если я хочу изменить вектор строки, в MATLAB я бы ввел reshape (s,[4,1]), чтобы получить вектор столбца.

Я бы предположил, что стандартным обозначением для эквивалентной операции является s.reshape (4,1). Но в документации я вижу s.reshape(-1,1). Почему? Один синтаксис лучше другого? Что означает -1 в этом контексте?

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

1. numpy имеет реальные одномерные массивы,

2. строки и столбцы являются удобными дескрипторами для 2d-массивов. Они формально не определены и не используются. numpy всегда говорит об осях.

3. Это -1 в reshape ‘то, что когда-либо работает’. MATLAB использует [] для этого.

Ответ №1:

Отступите на numpy мгновение и посмотрите на списки Python:

 In [165]: alist = [0,3,6,9]                                                     
In [166]: alist                                                                 
Out[166]: [0, 3, 6, 9]
In [167]: alist[1]                                                              
Out[167]: 3
  

Это 3 скаляр; я бы получил сообщение об ошибке, если бы попытался его проиндексировать, alist[1][0] .

Теперь составьте список списков:

 In [168]: alist = [[0],[3],[6],[9]]                                             
In [169]: alist                                                                 
Out[169]: [[0], [3], [6], [9]]
In [170]: alist[1]                                                              
Out[170]: [3]
In [171]: alist[1][0]                                                           
Out[171]: 3
  

Я могу проиндексировать его дважды.

В Octave MATLAB бедняги

 >> x = [0,3,6,9];
>> x(2)
ans =  3
>> size(x)
ans =
   1   4

>> size(x(2))
ans =
   1   1
  

x(2) это все еще 2d-матрица; я мог бы индексировать ее бесконечно, x(2)(1)(1)(1) . Размер сам по себе является 2d-матрицей; все в MATLAB является 2d (или выше).

 >> size(size(x))
ans =
   1   2
  

Снова в Python / numpy:

 In [172]: arr = np.array([0,3,6,9])                                             
In [173]: arr.shape                                                             
Out[173]: (4,)             # a 1 element tuple

In [175]: arr[1]                                                                
Out[175]: 3
In [176]: type(Out[175])                                                        
Out[176]: numpy.int64
In [177]: Out[175].shape                                                        
Out[177]: ()
  

Результатом индексации элемента этого одномерного массива является скалярный объект numpy с 0d формой. https://docs.scipy.org/doc/numpy/reference/arrays.scalars.html

Судя по многим вопросам, кажется, что у пользователей MATLAB возникают проблемы с представлением массива с 1 или даже 0 размерами. Эта нижняя 2d-граница полностью укоренилась в их мышлении. Это также кажется основополагающим для некоторых (если не для всех) версий линейной алгебры. Существуют матрицы, векторы строк и векторы столбцов, но не «простые» векторы.

Но numpy выполняется на Python, и поведение его массивов согласуется со списками Python. И логически согласуется с самим собой.

Вот как выглядят векторы ‘column’ и ‘row’. Обратите внимание на формы — оба кортежа из двух элементов. И вложенность скобок (2 уровня). Сходство с вложенным списком является преднамеренным.

 In [178]: arr = np.array([[0],[3],[6],[9]])                                     
In [179]: arr.shape                                                             
Out[179]: (4, 1)
In [180]: arr                                                                   
Out[180]: 
array([[0],
       [3],
       [6],
       [9]])
In [181]: arr = np.array([[0,3,6,9]])                                           
In [182]: arr.shape                                                             
Out[182]: (1, 4)
In [183]: arr                                                                   
Out[183]: array([[0, 3, 6, 9]])