2017-10-17 7 views
1
a=b=np.arange(9).reshape(3,3) 
i=np.arange(3) 
mask=a<i[:,None,None]+3 

etvectorisation: trop d'indices pour tableau

b[np.where(mask[0])] 
>>>array([0, 1, 2]) 

b[np.where(mask[1])] 
>>>array([0, 1, 2, 3]) 

b[np.where(mask[2])] 
>>>array([0, 1, 2, 3, 4]) 

Maintenant, je veux vectoriser et les imprimer tous ensemble, et j'essaie

b[np.where(mask[i])] et b[np.where(mask[i[:,None,None]])]

Les deux montrent IndexError: too many indices for array

+0

Je ne suis pas sûr que cela fasse ce que vous voulez du tout. En particulier, 'np.where (mask [0]) [0]' est tout 'True's parce que la valeur de vérité de tableaux est prise (et est' True' si au moins un élément est vrai), et aussi vous êtes en utilisant les deux valeurs de retour de 'np.where()', ce que je ne pense pas est ce que vous voulez. – remram

Répondre

0

En essayant pour imprimer un vecteur, il ne peut exister que dans les dimensions x, y et z. Vous avez 4.

+1

N'avez-vous jamais vu un vecteur avec plus de 3 dimensions? –

1
In [165]: a 
Out[165]: 
array([[0, 1, 2], 
     [3, 4, 5], 
     [6, 7, 8]]) 
In [166]: mask 
Out[166]: 
array([[[ True, True, True], 
     [False, False, False], 
     [False, False, False]], 

     [[ True, True, True], 
     [ True, False, False], 
     [False, False, False]], 

     [[ True, True, True], 
     [ True, True, False], 
     [False, False, False]]], dtype=bool) 

Alors a (et b) est (3,3), alors que mask est (3,3,3).

Un masque boolean, appliqué à un réseau produit une 1d (même lorsqu'elles sont appliquées par l'intermédiaire d'where):

In [170]: a[mask[1,:,:]] 
Out[170]: array([0, 1, 2, 3]) 

Le where sur le masque 2d produit un tuple de l'élément 2, dont l'indice peut le tableau 2D:

In [173]: np.where(mask[1,:,:]) 
Out[173]: (array([0, 0, 0, 1], dtype=int32), array([0, 1, 2, 0], dtype=int32)) 

where sur le masque 3D est un élément 3 tuple - d'où l'erreur too many indices:

In [174]: np.where(mask) 
Out[174]: 
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2], dtype=int32), 
array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1], dtype=int32), 
array([0, 1, 2, 0, 1, 2, 0, 0, 1, 2, 0, 1], dtype=int32)) 

Essayons expansion a à 3d et appliquer le masque

In [176]: np.tile(a[None,:],(3,1,1)).shape 
Out[176]: (3, 3, 3) 
In [177]: np.tile(a[None,:],(3,1,1))[mask] 
Out[177]: array([0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4]) 

Les valeurs sont là, mais ils sont joints.

Nous pouvons compter le nombre de True dans chaque plan de mask, et l'utiliser pour split la tuile masquée:

In [185]: mask.sum(axis=(1,2)) 
Out[185]: array([3, 4, 5]) 
In [186]: cnt=np.cumsum(mask.sum(axis=(1,2))) 
In [187]: cnt 
Out[187]: array([ 3, 7, 12], dtype=int32) 

In [189]: np.split(np.tile(a[None,:],(3,1,1))[mask], cnt[:-1]) 
Out[189]: [array([0, 1, 2]), array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])] 

interne np.split utilise une itération de niveau Python. Donc l'itération sur les plans mask pourrait être tout aussi bonne (6x plus rapide sur ce petit exemple).

In [190]: [a[m] for m in mask] 
Out[190]: [array([0, 1, 2]), array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])] 

qui pointe vers un problème fondamental désiré 'vectorisation', les réseaux individuels sont (3,), (4), et (5), forme. Des tableaux de tailles différentes sont un indicateur fort que la véritable «vectorisation» est difficile, voire impossible.