2015-06-02 6 views
8

Ich bemerkte etwas verwirrendes Verhalten, wenn er ein flaches numpy Array mit einer Liste der Tupel indexierte (mit Python 2.7.8 und numpy 1.9.1). Meine Vermutung ist, dass dies mit der maximalen Anzahl von Array-Dimensionen zusammenhängt (was meiner Meinung nach 32 ist), aber ich konnte die Dokumentation nicht finden.Merkwürdiges Verhalten des Tupel, das ein numply Feld indexiert

>>> 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... 

Wird die Liste der Tupel "abgeflacht", wenn sie 32 Elemente oder größer ist? Ist das irgendwo dokumentiert?

+1

Interessant, bekomme ich eine andere Fehlermeldung: 'IndexError: nicht unterstützten Iterator-Index '. Mit Python 2.7 und numpy 1.8.2 – swenzel

+0

Sorry, ich hätte die Versionen (Python 2.7.8; numpy 1.9.1) angegeben. Ich habe die Frage aktualisiert. – kadrlica

Antwort

5

Der Unterschied scheint zu sein, dass die ersten Beispiele eine fancy-Indizierung auslösen (die einfach Indizes in einer Liste aus derselben Dimension auswählt), während tuple_index[:31] stattdessen als Indizierungstupel behandelt wird (was Auswahl aus mehreren Achsen impliziert).

Wie Sie bemerkt, die maximale Anzahl von Dimensionen für eine NumPy Array ist (in der Regel) 32:

>>> np.MAXDIMS 
32 

Gemäß dem folgenden Kommentar in der mapping.c-Datei (die den Code enthält den Index durch geben zu interpretieren der Benutzer), eine beliebige Sequenz von Tupeln kürzer als 32 ist mit einem Indexierungs Tupel abgeflacht.

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

(ich habe noch nicht eine Referenz für diese in der offiziellen Dokumentation auf der SciPy Website gefunden)

Dies macht a[tuple_index[:3]] entspricht a[(0,), (1,), (2,)], daher der "zu viele Indizes" Fehler (weil a nur eine Dimension hat, aber wir implizieren, es gibt drei).

Auf der anderen Seite ist a[tuple_index] genau das gleiche wie a[[(0,), (1,), (2,), ..., (99,)]] in der 2D-Array.

+0

Die [Grundlagen-Dokumentation] (http://docs.scipy.org/doc/numpy/user/basics.indexing.html) behauptet, dass * Index-Arrays vom Integer-Typ sein müssen. * Offenbar erlaubt die Implementierung dies sowieso. Was ich immer noch nicht herausfinden kann, ist, warum Sie ein 2D-Array aus der Liste der Tupel erhalten, die größer sind als 'np.MAXDIMS'. –

+0

Ich stimme zu, es scheint nicht offensichtlich (und ich weiß nicht, ob es beabsichtigt ist oder nicht). Wenn länger als 'MAXDIMS' [wie es aussieht] (https://github.com/numpy/numpy/blob/1f6e7cc470c6d5af23b2467863f42108e6c5f545/numpy/core/src/multiarray/mapping.c#l395) die Liste der Tupel' [(0 ,), (1,), (2,) ..., (99,)] wird intern in ein NumPy-Array umgewandelt (es wird ein 2D-Array). Dies wird dann verwendet, um das ursprüngliche 1D-Array zu indizieren (ein 2D-Array wird zurückgegeben). –

Verwandte Themen