2015-06-02 2 views
8

Я заметил некоторое запутанное поведение при индексировании плоского массива numpy со списком кортежей (с использованием python 2.7.8 и numpy 1.9.1). Я предполагаю, что это связано с максимальным количеством измерений массива (я считаю, это 32), но я не смог найти документацию.Странное поведение индексирования кортежа массивом numpy

>>> a = np.arange(100) 
>>> tuple_index = [(i,) for i in a] 
>>> a[tuple_index] # This works (but maybe it shouldn't) 
>>> a[tuple_index[:32]] # This works too 
>>> a[tuple_index[:31]] # This breaks for 2 <= i < 32 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: too many indices for array 
>>> a[tuple_index[:1]] # This also works... 

Является ли список кортежей «сплющенным», если он составляет 32 элемента или больше? Это где-то документально?

+1

Интересно, я получаю другое сообщение об ошибке: 'IndexError: неподдерживаемый индекс итератора'. Использование python 2.7 и numpy 1.8.2 – swenzel

+0

К сожалению, я должен был указать версии (python 2.7.8; numpy 1.9.1). Я обновил вопрос. – kadrlica

ответ

5

Разница заключается в том, что первые примеры запускают причудливое индексирование (которое просто выбирает индексы в списке из того же размера), тогда как tuple_index[:31] вместо этого рассматривается как индексирующий кортеж (что подразумевает выбор из нескольких осей).

Как отмечался выше, максимальное количество измерений для массива NumPy (обычно) 32:

>>> np.MAXDIMS 
32 

Согласно следующему комментарию в файле mapping.c (который содержит код для интерпретации индекса, принятого пользователь), любая последовательность кортежей короче 32 сплющивается к индексации кортежа:.

/* 
* Sequences < NPY_MAXDIMS with any slice objects 
* or newaxis, Ellipsis or other arrays or sequences 
* embedded, are considered equivalent to an indexing 
* tuple. (`a[[[1,2], [3,4]]] == a[[1,2], [3,4]]`) 
*/ 

(я еще не нашел ссылку на это в официальной документации на сайте SciPy)

Это делает a[tuple_index[:3]] эквивалентом a[(0,), (1,), (2,)], поэтому ошибка «слишком много индексов» (потому что a имеет только одно измерение, но мы подразумеваем, что есть три).

С другой стороны, a[tuple_index] - это то же самое, что и a[[(0,), (1,), (2,), ..., (99,)]], что приводит к 2D-массиву.

+0

[Основная документация] (http://docs.scipy.org/doc/numpy/user/basics.indexing.html) утверждает, что * Индексные массивы должны быть целочисленного типа. * По-видимому, реализация позволяет это в любом случае. Я все еще не могу понять, почему вы получаете 2D-массив из списка кортежей больше, чем 'np.MAXDIMS'. –

+0

Я согласен, что это не кажется очевидным (и я не знаю, предназначено это или нет). Когда дольше, чем 'MAXDIMS' [выглядит как] (https://github.com/numpy/numpy/blob/1f6e7cc470c6d5af23b2467863f42108e6c5f545/numpy/core/src/multiarray/mapping.c#l395), список кортежей' [(0 ,), (1,), (2,) ..., (99,)] 'внутренне передается в массив NumPy (он станет 2D-массивом). Затем он используется для индексации исходного массива 1D (возвращающего 2D-массив). –

Смежные вопросы