2015-06-02 32 views
8

Ho notato un comportamento confuso durante l'indicizzazione di una matrice numerica piatta con un elenco di tuple (utilizzando python 2.7.8 e numpy 1.9.1). La mia ipotesi è che questo è legato al numero massimo di dimensioni dell'array (che credo sia 32), ma non sono stato in grado di trovare la documentazione.Strano comportamento della tupla indicizzazione di una matrice 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... 

L'elenco di tuple viene "appiattito" se è 32 elementi o più grande? Questo è documentato da qualche parte?

+1

Interessante, viene visualizzato un messaggio di errore diverso: "IndexError: indice iteratore non supportato". Usando python 2.7 e numpy 1.8.2 – swenzel

+0

Spiacente, avrei dovuto specificare le versioni (python 2.7.8; numpy 1.9.1). Ho aggiornato la domanda. – kadrlica

risposta

5

La differenza sembra essere che i primi esempi attivano l'indicizzazione di fantasia (che seleziona semplicemente gli indici in una lista dalla stessa dimensione) mentre tuple_index[:31] viene invece considerato come una tupla di indicizzazione (che implica la selezione da più assi).

Come annotato, il numero massimo di dimensioni per un array NumPy è (solitamente) 32:

>>> np.MAXDIMS 
32 

Secondo il seguente commento nel file mapping.c (che contiene il codice per interpretare l'indice passò l'utente), qualsiasi sequenza di tuple di lunghezza inferiore a 32 è appiattita a una tupla indicizzazione:.

/* 
* 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]]`) 
*/ 

(non ho ancora trovato un punto di riferimento per questo nella documentazione ufficiale sul sito SciPy)

Questo rende a[tuple_index[:3]] equivalente a a[(0,), (1,), (2,)], quindi l'errore "troppi indici" (perché a ha una sola dimensione ma stiamo implicando che ce ne sono tre).

D'altra parte, a[tuple_index] è lo stesso di a[[(0,), (1,), (2,), ..., (99,)]] risultante nell'array 2D.

+0

La [documentazione di base] (http://docs.scipy.org/doc/numpy/user/basics.indexing.html) afferma che * Gli array dell'indice devono essere di tipo intero. * Apparentemente l'implementazione lo consente comunque. Quello che ancora non riesco a capire è il motivo per cui ottieni un array 2D dalla lista di tuple maggiore di 'np.MAXDIMS'. –

+0

Sono d'accordo che non sembra ovvio (e non so se è inteso o no). Quando è più lungo di 'MAXDIMS' [sembra] (https://github.com/numpy/numpy/blob/1f6e7cc470c6d5af23b2467863f42108e6c5f545/numpy/core/src/multiarray/mapping.c#l395) l'elenco di tuple' [(0 ,), (1,), (2,) ..., (99,)] 'è internamente convertito in un array NumPy (diventerà un array 2D). Questo viene quindi utilizzato per indicizzare l'array 1D originale (restituendo un array 2D). –

Problemi correlati