Почему индексирование столбца Numpy создает копию, но не для строк или массивов 1D? - PullRequest
1 голос
/ 02 апреля 2020

Скажем, у меня есть массив с именем array1D:

array1D

array([0, 1, 2, 3, 4, 5])

Затем я беру его срез и присваиваю его значения 22 * ​​1004 *

slice_of_array1D = array1D[0:3]
slice_of_array1D[:] = 22

Если я проверю исходный массив, я получил мой фрагмент from, первые 3 значения также изменяются на 22 * ​​1007 *

array1D

array([22, 22, 22,  3,  4,  5])

Теперь я понимаю, что это сделано для экономии памяти, поскольку slice_of_array1D просто ссылается на array1D, а не создает копию, что потребовало бы использования array1D. копия (). Однако, что меня смущает, так это то, почему он не делает этого и для столбцов матриц. Вот пример:

array2D

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

Теперь давайте возьмем срез array2D, первый столбец, и вызовем его, просто чтобы показать, как он выглядит:

slice_of_array2D = array2D[:,[0]]

slice_of_array2D

array([[1],
       [4],
       [7]])

Теперь давайте назначим значения среза до 22, вызовите срез, а затем вызовите исходный массив 2D

slice_of_array2D[:] = 22

slice_of_array2D

array([[22],
       [22],
       [22]])

array2D

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

Видите, как исходный массив 2D остается неизменным? Почему это происходит? Выполнение этого для строк вместо столбцов действительно изменяет значения в исходной матрице, так же, как это происходит с одномерными массивами. Однако, как вы видели выше, столбцы кажутся невосприимчивыми. Теперь, есть ли причина / обоснование для этого в Python? Я спрашиваю, потому что я учу Python / Numpy использовать его вместо MATLAB, поэтому большая часть моей работы будет использовать матрицы и линейную алгебру и т. Д. c. Я надеюсь, что, может быть, логическое обоснование того, почему это происходит, понимая, как Python / Numpy «думает», облегчит мне работу с ним.

Спасибо, друзья! Я прошу прощения за длинный вопрос, но я хотел включить всю информацию, которая может иметь отношение к делу:)

1 Ответ

1 голос
/ 03 апреля 2020

Вот лишь несколько вариантов индексации:

In [431]: arr = np.arange(1,13).reshape(3,4)                                                   
In [432]: arr                                                                                  
Out[432]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

Индекс со скаляром уменьшает размерность (и):

In [433]: arr[1]                                                                               
Out[433]: array([5, 6, 7, 8])      # (4,)
In [434]: arr[:,1]                                                                             
Out[434]: array([ 2,  6, 10])      # (3,)

Доступ к этим элементам все еще возможен:

In [435]: arr[:,1] +=10                                                                        
In [436]: arr                                                                                  
Out[436]: 
array([[ 1, 12,  3,  4],
       [ 5, 16,  7,  8],
       [ 9, 20, 11, 12]])

Индекс со списком сохраняет размерность (и):

In [437]: arr[:,[1]]                                                                           
Out[437]:                 # (3,1) 
array([[12],
       [16],
       [20]])
In [438]: arr[[1]]                                                                             
Out[438]: array([[ 5, 16,  7,  8]])     # (1,3)

Индекс со списком из нескольких элементов; завершающий: необязательный:

In [439]: arr[[1,2],:]                                                                         
Out[439]: 
array([[ 5, 16,  7,  8],
       [ 9, 20, 11, 12]])

индекс с несколькими массивами - здесь «диагональный» выбор (сложнее сделать в MATLAB):

In [440]: arr[[1,2],[1,2]]                                                                     
Out[440]: array([16, 11])

здесь выбор блока (типичный MATLAB):

In [441]: arr[[[1],[2]],[1,2]]                                                                 
Out[441]: 
array([[16,  7],
       [20, 11]])

То же выделение с кусочками (вид):

In [442]: arr[1:3,1:3]                                                                         
Out[442]: 
array([[16,  7],
       [20, 11]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...