Разница arr[range(3)] против arr [:3] в numpy

#python

#python

Вопрос:

У меня есть простой код скрипта, поэтому я не знаю, почему элементы в numpy не меняются местами. Спасибо ^^

 import numpy as np

arr = np.arange(10)

a = arr[range(3)]
b = arr[:3]
c = arr[3:6]

# Can swap
arr[range(3)], arr[3:6] = arr[3:6],arr[range(3)] 

# Can't swap
arr[:3], arr[3:6] = arr[3:6],arr[:3]
  

Ответ №1:

Базовые фрагменты в numpy — это представления части массива, тогда как расширенная индексация создает копию соответствующей части массива.

Из документации:

Расширенная индексация всегда возвращает копию данных (в отличие от базовой нарезки, которая возвращает представление).

arr[range(3)] является примером расширенного индексирования. Вы можете увидеть это, если попытаетесь присвоить элементам a :

 >>> arr = np.arange(10)
>>> a = arr[range(3)]
>>> a[0] = 11
>>> a
array([11,  1,  2])
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  

в отличие от этого, arr[:3] является базовым фрагментом и дает представление о массиве:

 >>> arr = np.arange(10)
>>> b = arr[:3]
>>> b[0] = 11
>>> b
array([11,  1,  2])
>>> arr
array([11,  1,  2,  3,  4,  5,  6,  7,  8,  9])
  

Попытка поменять местами, используя два представления массива, не работает, потому что временный кортеж аналогично содержит два представления массива. У вас нет отдельной временной копии данных, которая была бы необходима для правильного выполнения подкачки.

На самом деле, чтобы правильно выполнить обмен, вам не нужна расширенная индексация в левой части назначения. Достаточно сделать это только с правой стороны:

 >>> arr = np.arange(10)
>>> arr[:3], arr[3:6] = arr[3:6],arr[range(3)] 
>>> arr
array([3, 4, 5, 0, 1, 2, 6, 7, 8, 9])
  

Или сделайте копию:

 >>> arr = np.arange(10)
>>> arr[:3], arr[3:6] = arr[3:6],arr[:3].copy()
>>> arr
array([3, 4, 5, 0, 1, 2, 6, 7, 8, 9])
  

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

1. спасибо за ответ, так что могу я задать вам вопрос? список arr по-прежнему сохраняет значение при изменении c [1] >>> arr = [1,2,3,4,5,6] >>> c = arr [:] >>> c [1] = 4 #печать arr = [1, 2, 3, 4, 5, 6]

2. @superbrain Я немного перефразирую «аналогично» вместо также. Я имел в виду «также», как в «точно так же, как в приведенном выше примере», а не «в дополнение к чему-то еще в том же заявлении».

3. @Quang.tpa Ваш arr пример в комментарии просто представляет собой список, а не массив numpy. Попробуйте это с arr = np.array([1,2,3,4,5,6]) , и вы увидите разницу. Фрагменты списков являются копиями.

4. Не могли бы вы расширить Trying to swap using two views of the array does not work... ? Почему два представления одного и того же массива не могут быть сохранены в стеке?

5. @yatu Представления именно такие: представления. Даже если эти нарезанные объекты массива где-то сохранены, например, временный кортеж из 2 элементов, они все равно указывают на исходный объект массива, когда дело доходит до извлечения значений. После того, как вы скопировали arr[3:6] в arr[:3] , у вас больше нигде не будет исходного содержимого arr[:3] .