Quel serait le moyen le plus rapide de vérifier si un tableau numpy multidimensionnel a 0 de tous les côtés.
Donc, pour un exemple 2D simple, j'ai:
x = np.random.rand(5, 5)
assert np.sum(x[0:, 0]) == 0
assert np.sum(x[0, 0:]) == 0
assert np.sum(x[0:, -1]) == 0
assert np.sum(x[-1, 0:]) == 0
Bien que cela soit correct pour les cas 2D à droite, l'écriture pour des dimensions plus élevées est un peu fastidieuse et je me demandais s'il y avait une astuce numpy intelligente que je peux utiliser ici pour la rendre efficace et plus facile à maintenir.
np.all (x[:, 0] == 0)
plus sûr que la somme? Le test de somme n'est correct que si tous les nombres sont positifs.Réponses:
Voici comment procéder:
np.take
fait la même chose que l'indexation "fantaisie".la source
numpy.take
fait une copie. Cela peut entraîner des performances inférieures à celles du code basé sur une vue. (Le timing serait nécessaire pour être sûr - L'efficacité de la vue NumPy est parfois bizarre.)len(x.shape)
peut être écrit plus simplement commex.ndim
.all
courts-circuits. Vous pouvez supprimer les crochets pour utiliser une expression de générateur, permettantall
de retourner dès qu'un seulnumpy.all
appel revientFalse
.Voici une réponse qui examine réellement les parties du tableau qui vous intéressent et ne perd pas de temps à construire un masque de la taille de l'ensemble du tableau. Il y a une boucle au niveau Python, mais elle est courte, avec des itérations proportionnelles au nombre de dimensions au lieu de la taille du tableau.
la source
not (view[0] == 0).all()
n'est pas équivalent àview[0].any()
?view[0].any()
cela fonctionnerait aussi. Je ne suis pas entièrement sûr des implications en termes d'efficacité de la conversion et de la mise en mémoire tampon impliquées dans les deux options -view[0].any()
pourraient théoriquement être mises en œuvre plus rapidement, mais j'ai déjà vu des résultats étranges auparavant, et je ne comprends pas complètement la mise en mémoire tampon impliquée.view[0].view(bool).any()
serait la solution à grande vitesse.argmax
pourrait en fait battreany
la vue booléenne . Ce truc devient bizarre.argmax
ouany
, l'utilisation d'une vue booléenne signifie que le zéro négatif est différent du zéro normal.)J'ai remodelé le tableau, puis itéré à travers lui. Malheureusement, ma réponse suppose que vous avez au moins trois dimensions et que vous vous tromperez pour les matrices normales, vous devrez ajouter une clause spéciale pour les tableaux en forme 1 et 2 dimensions. De plus, cela sera lent donc il y a probablement de meilleures solutions.
Qui produira
Fondamentalement, j'empile toutes les dimensions les unes sur les autres, puis je les regarde pour vérifier leurs bords.
la source
peut-être que l'opérateur des points de suspension est ce que vous recherchez, qui fonctionnera pour de nombreuses dimensions:
la source
Vous pouvez utiliser le
slice
masquage booléen pour faire le travail:Cette fonction façonne d'abord le «noyau» du tableau dans le tuple
s
, puis crée un masque qui s'afficheTrue
uniquement pour les points limitrophes. L'indexation booléenne délivre ensuite les points frontières.Exemple de travail:
Ensuite,
np.all(borders==0)
vous donnera les informations souhaitées.Remarque: cela se casse pour les tableaux unidimensionnels, bien que je considère ceux-ci comme un cas de bord. Vous feriez probablement mieux de vérifier les deux points en question
la source
np.arange(15)
ne comprend pas 15.