Размерность результата индексации ndarray со срезом в диапазоне - PullRequest
0 голосов
/ 20 января 2019

Я пытаюсь понять использование range в качестве индекса и сравнить его с использованием слайса в качестве индекса на ndarray. В частности, влияние на размерность результата.

Я понимаю, что:

  1. Для данного измерения (скажем, 0-го измерения) ndarray, если я использую скалярный индекс, такой как 2, это приводит к тому, что размерность результата меньше размерности оригинал ndarray, на 1.

  2. Для того же (0-го) измерения вместо скаляра 2, если я использую slice(2,3), указанное уменьшение размерности не произойдет.

По большей части, если я использую range вместо slice, эффект (на размерность) будет таким же, но для одного особого случая.

Вот код. Сюрприз для меня в 4-м заявлении:

import numpy as np

nd15 = np.array([['e00','e01','e02','e03'],
                 ['e10','e11','e12','e13'], 
                 ['e20','e21','e22','e23']])

# Consider the dimensionality of the indexing results from the below 4 
# lines.
# From the first 3 print statements, we are led to believe that, if you
# replace a range with an "equivalent" slice-expression, the
# dimensionality of the result will remain unchanged.
# But the fourth result below surprisingly negates that understanding.
print (nd15[slice(2,3), slice(2,3)].shape)
print (nd15[slice(2,3), range(2,3)].shape)
print (nd15[range(2,3), slice(2,3)].shape)
print (nd15[range(2,3), range(2,3)].shape)

Я ожидал, что четвертый отпечаток также даст тот же результат, что и остальные три.

Вместо этого я получил следующий результат:

(1, 1)
(1, 1)
(1, 1)
(1,)

Что мне не хватает?

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Ваши выражения среза и диапазона также могут быть записаны как:

In [86]: nd15[2:3, 2:3]
Out[86]: array([['e22']], dtype='<U3')
In [87]: nd15[2:3, [2]]
Out[87]: array([['e22']], dtype='<U3')
In [88]: nd15[[2],2:3]
Out[88]: array([['e22']], dtype='<U3')
In [89]: nd15[[2],[2]]
Out[89]: array(['e22'], dtype='<U3')

nd15[2,2] будет скалярным элементом 'e22'.

Но различия могут быть более ясными, если мы расширимкусочки для получения массива (2,2):

In [97]: nd15[1:3, 2:4]
Out[97]: 
array([['e12', 'e13'],
       ['e22', 'e23']], dtype='<U3')
In [98]: nd15[1:3,[2,3]]
Out[98]: 
array([['e12', 'e13'],
       ['e22', 'e23']], dtype='<U3')
In [99]: nd15[[1,2], 2:4]
Out[99]: 
array([['e12', 'e13'],
       ['e22', 'e23']], dtype='<U3')
In [100]: nd15[[1,2], [2,3]]
Out[100]: array(['e12', 'e23'], dtype='<U3')

Последний является диагональю, (1,2) и (2,3) элементов.

Out[86] и Out[97] views, остальные копии.

0 голосов
/ 20 января 2019

Вы запускаете два различных типа расширенного индексирования , не осознавая этого из-за неявного преобразования range в ndarray.

Когда у вас есть range или list (или любой другой реально повторяемый) в обоих индексах, вы запускаете индексирование целочисленного массива . В этой схеме результат будет иметь ту же форму, что и переданные индексные массивы. В данном случае это одномерный массив, потому что в него преобразуются диапазоны.

Когда один индекс является итеративным, а другой - слайсом, вы запускаете форму гибридной индексации . В этом случае форма имеет комбинацию размеров из расширенного индекса (1) и среза (1). Если бы вы указали 2D-вложенный список вместо range для расширенного индекса, вы бы получили 3D-вывод.

...