Различия в использовании range () или slice () для нарезки 2-го массива - PullRequest
1 голос
/ 02 марта 2020

Когда я пытался узнать, как работает slice (), я столкнулся с некоторыми интересными результатами при использовании range () и slice (). Я не знаю, как объяснить механизм. Любая помощь будет оценена.

Например: для массива np:

a = np.array(range(100)).reshape(10,10)

a[slice(0,10,2)] и a[range(0,10,2)] идентичны.

однако,

a[(slice(0,10,2),slice(0,10,2))] 

это

[[0,2...],[20,22...],[40,42,44]...]

но

a[(range(0,10,2),range(0,10,2))] 

это

[0,22,44,66...]

Кто-нибудь может это объяснить?

1 Ответ

1 голос
/ 02 марта 2020

Индексирование по диапазону и индексирование по срезу - это, в общем, две совершенно разные вещи. Вы столкнулись с делом, которое дает равные результаты, хотя обратите внимание, что версия среза создает представление нижележащего буфера, тогда как индексирование с помощью объектов range создает новый нижележащий буфер.

Итак, обратите внимание:

>>> a = np.array(range(100)).reshape(10,10)
>>> s = a[slice(0,10,2)]
>>> r = a[range(0,10,2)]
>>> a[0,0] = 1000
>>> a
array([[1000,    1,    2,    3,    4,    5,    6,    7,    8,    9],
       [  10,   11,   12,   13,   14,   15,   16,   17,   18,   19],
       [  20,   21,   22,   23,   24,   25,   26,   27,   28,   29],
       [  30,   31,   32,   33,   34,   35,   36,   37,   38,   39],
       [  40,   41,   42,   43,   44,   45,   46,   47,   48,   49],
       [  50,   51,   52,   53,   54,   55,   56,   57,   58,   59],
       [  60,   61,   62,   63,   64,   65,   66,   67,   68,   69],
       [  70,   71,   72,   73,   74,   75,   76,   77,   78,   79],
       [  80,   81,   82,   83,   84,   85,   86,   87,   88,   89],
       [  90,   91,   92,   93,   94,   95,   96,   97,   98,   99]])
>>> s
array([[1000,    1,    2,    3,    4,    5,    6,    7,    8,    9],
       [  20,   21,   22,   23,   24,   25,   26,   27,   28,   29],
       [  40,   41,   42,   43,   44,   45,   46,   47,   48,   49],
       [  60,   61,   62,   63,   64,   65,   66,   67,   68,   69],
       [  80,   81,   82,   83,   84,   85,   86,   87,   88,   89]])
>>> r
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89]])

Когда вы используете слайс, вы получите семантику слайса. Объект диапазона обрабатывается как последовательность индексов. Это запускает расширенное поведение при индексировании

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

Когда индекс состоит из такого количества целочисленных массивов, что у индексируемого массива есть измерения, индексирование прямо вперед, но отличается от нарезки.

так, ARR[[x1, x2, ..., xn], [y1, y2, ..., yn]] даст вам что-то вроде

[ARR[x1,y1], ARR[x2,y2], ... ARR[xn, yn]]

Как @ShadowRanger отмечает в комментариях, если вы Если вы хотите семантику копирования с использованием индексации диапазона, вам все равно, вероятно, следует использовать a[:10:2,:10:2].copy(), потому что это будет быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...