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