Un'alternativa a np.ix_
è quello di convertire gli array booleani in numero intero array (usando np.nonzero()
), quindi utilizzare np.newaxis
per creare matrici della forma corretta per sfruttare la trasmissione.
import numpy as np
a=np.random.rand(10,20)
x_range=np.arange(10)
y_range=np.arange(20)
a_tmp=a[x_range<5,:]
b_correct=a_tmp[:,np.in1d(y_range,[3,4,8])]
m1=(x_range<5).nonzero()[0]
m2=np.in1d(y_range,[3,4,8]).nonzero()
b=a[m1[:,np.newaxis], m2]
assert np.allclose(b,b_correct)
b2=a[np.ix_(x_range<5,np.in1d(y_range,[3,4,8]))]
assert np.allclose(b2,b_correct)
np.ix_
tende ad essere più lento del doppio indicizzazione. La soluzione a lungo modulo sembra essere un po 'più veloce:
long-form:
In [83]: %timeit a[(x_range<5).nonzero()[0][:,np.newaxis], (np.in1d(y_range,[3,4,8])).nonzero()[0]]
10000 loops, best of 3: 131 us per loop
doppia indicizzazione:
In [85]: %timeit a[x_range<5,:][:,np.in1d(y_range,[3,4,8])]
10000 loops, best of 3: 144 us per loop
utilizzando np.ix_:
In [84]: %timeit a[np.ix_(x_range<5,np.in1d(y_range,[3,4,8]))]
10000 loops, best of 3: 160 us per loop
Nota: sarebbe una buona idea testare questi tempi sul dispositivo poiché le classifiche potrebbero cambiare in base alla versione di Python, numpy o hardware.
In realtà non ha senso. Chiederò al maillista perché è così. – tillsten
[scipy.org/Cookbook/Indexing](http://scipy.org/Cookbook/Indexing) p. 14 sull'Indice Booleano Multidimenionale dice "guarda gli strumenti dell'array mascherato di numpy ... L'approccio ovvio non dà la risposta giusta". (Questo documento è ben scritto, deve essere aggiornato.) – denis
@denis, circa 2013 questo documento lo spiega piuttosto bene. Tuttavia, se si utilizza l'indicizzazione logica google numpy, il documento che appare è http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html e non è spiegato quasi altrettanto bene. – John