2016-04-28 4 views
1

Ist es möglich, Einträge aus einem nd-Array nachzuschlagen, ohne eine IndexError zu werfen?Standardwert bei Indexierung außerhalb eines numpy-Arrays, selbst bei nicht-trivialer Indexierung

Ich hoffe auf so etwas wie:

>>> a = np.arange(10) * 2 
>>> a[[-4, 2, 8, 12]] 
IndexError 
>>> wrap(a, default=-1)[[-4, 2, 8, 12]] 
[-1, 4, 16, -1] 

>>> wrap(a, default=-1)[200] 
-1 

Oder vielleicht eher wie get_with_default(a, [-4, 2, 8, 12], default=-1)

Gibt es eine eingebaute Möglichkeit, dies zu tun? Kann ich numpy fragen, die Ausnahme nicht zu werfen und Müll zurückzugeben, den ich dann mit meinem Standardwert ersetzen kann?

Antwort

2

np.take mit clip Modus, eine Art erledigt diese

In [155]: a 
Out[155]: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]) 

In [156]: a.take([-4,2,8,12],mode='raise') 
... 
IndexError: index 12 is out of bounds for size 10 

In [157]: a.take([-4,2,8,12],mode='wrap') 
Out[157]: array([12, 4, 16, 4]) 

In [158]: a.take([-4,2,8,12],mode='clip') 
Out[158]: array([ 0, 4, 16, 18]) 

Außer Sie nicht viel Kontrolle über den Rückgabewert haben kann - hier Indizierung auf 12 return 18, dem letzten Wert. Und behandelte -4 als außerhalb der Grenzen in der anderen Richtung, Rückkehr 0.

Eine Möglichkeit, die Standardeinstellung des Hinzufügens zu Pad a ersten

In [174]: a = np.arange(10) * 2 
In [175]: ind=np.array([-4,2,8,12]) 

In [176]: np.pad(a, [1,1], 'constant', constant_values=-1).take(ind+1, mode='clip') 
Out[176]: array([-1, 4, 16, -1]) 

Nicht gerade schön, aber ein Anfang.

+0

Nah genug, danke! Das Auffüllen des Perimeters mit dem Standardwert würde ausreichen, um das zu ermöglichen. – Eric

+0

Hmm, 'np.take' funktioniert nicht mit den gleichen Indexierungsregeln wie' [] '. Gibt es eine einfache Möglichkeit, etwas wie "np.s_ [1, [2, 3, 4],:]" in ein passendes Objekt umzuwandeln? – Eric

+0

Tatsächlich scheint es, dass np.take nur mit dem einfachen Fall funktioniert. Vielleicht hätte ich stattdessen ein 2D-Array als Beispiel verwenden sollen. – Eric