2017-08-28 2 views
-1

Je suis sûr que c'est un doublon, mais je ne pouvais vraiment pas trouver la réponse ailleurs.Tranches de vues de la mémoire avec une liste d'indices

Mon problème principal est que j'utilise l'indexation booléenne numpy dans mon code et que je l'optimise.

je fais quelque chose comme:

y_ind = ~isnan(y) 
otheThing = y[t,y_ind[t,:]] 

La raison pour laquelle je sauve cette tranche dans otherThing est parce que je l'utilise pour plusieurs calculs, de sorte que j'évite reslicing chaque fois. Ma solution était d'utiliser des vues de mémoire au lieu de np.ndarray pour y et otherThing. Le problème est que l'indexation booléenne ne fonctionne pas dans Cython, de sorte que j'essaie de le découper avec une liste d'entiers. Tout comme nous le ferions dans numpy, quelque chose comme:

x = np.random.randn(5,5) 

array([[-0.56313056, -1.27834803, -0.30052179, -2.00063006, -2.05059544], 
     [-0.44563071, -0.63580159, -0.67538499, -0.9192516 , 0.49663121], 
     [ 2.11943794, -0.51746142, -0.80092609, -0.89391932, 1.91359607], 
     [ 0.52593344, -0.59931707, 0.78093441, -1.62449658, -1.65887717], 
     [-0.46422764, 0.96595406, -0.47142008, -0.28886925, -1.86674776]]) 

x[2,[1,2]] 

array([-0.51746142, -0.80092609]) 

Que se passe lorsque nous essayons de le faire est quelque chose comme:

cdef np.ndarray[np.double_t,ndim=2] a = np.random.randn(n,n) 
cdef double[:,:] a_mv = a 
print(np.array(a_mv[5,(1,3)])) 

.pyx:30:27: Invalid index for memoryview specified, type (long, long) 
In [22]: 

Est-il possible? Est-ce qu'il y a une meilleure approche ?

+2

Je modifierais la question pour mettre en évidence le problème 'cython', peut-être même en incluant une fonction' cython'. – hpaulj

+0

Quelqu'un a voté la question sans expliquer pourquoi. –

Répondre

2

Vous pouvez obtenir le tableau numpy sous-jacente d'un memoryview avec .base pour que vous puissiez faire

otheThing = y.base[t,y_ind[t,:]] 

(Le même fonctionneraient pour votre « liste des indices entiers »). Les vues de mémoire Cython sont assez limitées dans la façon dont vous pouvez les indexer - ce ne sont que des entiers et des tranches. Ils sont conçus pour être un moyen rapide d'accéder à la mémoire plutôt qu'à une classe de matrice complète. Il n'est pas possible d'obtenir une accélération de Cython quand on trie des choses de cette façon, donc si c'est tout ce que vous faites avec le memoryview, il n'y a aucun avantage à le taper - il suffit de le laisser comme un objet Python non typé . (Vous pouvez cependant faire quelque chose d'utile à l'avance bien sûr)