¿Cuál sería la forma más rápida de verificar si una matriz numpy multidimensional tiene 0 en todos los lados?
Entonces, para un ejemplo 2D simple, tengo:
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
Si bien esto está bien para casos 2D a la derecha, escribir para dimensiones más altas es un poco tedioso y me preguntaba si hay algún truco ingenioso y numpy que pueda usar aquí para hacerlo más eficiente y también más fácil de mantener.
np.all (x[:, 0] == 0)
sería más seguro que la suma? La prueba de suma es correcta solo si todos los números son positivos.Respuestas:
Así es como puedes hacerlo:
np.take
hace lo mismo que la indexación "elegante".fuente
numpy.take
hace una copia. Esto puede hacer que funcione peor que el código basado en una vista. (Momento sería necesario estar seguro - NumPy eficiencia de vista es a veces extraño.)len(x.shape)
se puede escribir más simplemente comox.ndim
.all
cortocircuitos. Puede eliminar los corchetes para usar una expresión generadora, loall
que permite regresar tan pronto comonumpy.all
regrese una sola llamadaFalse
.Aquí hay una respuesta que realmente examina las partes de la matriz que le interesan y no pierde el tiempo construyendo una máscara del tamaño de toda la matriz. Hay un bucle a nivel de Python, pero es corto, con iteraciones proporcionales al número de dimensiones en lugar del tamaño de la matriz.
fuente
not (view[0] == 0).all()
que no sea equivalenteview[0].any()
?view[0].any()
que también funcionaría. No estoy completamente seguro de las implicaciones de eficiencia de la conversión y el almacenamiento en búfer involucrados en las dos opciones: enview[0].any()
teoría podría implementarse más rápido, pero he visto resultados extraños antes, y no entiendo completamente el almacenamiento en búfer involucrado.view[0].view(bool).any()
que sería la solución de alta velocidad.argmax
realidad podría superarany
la vista booleana . Esto se pone raro.argmax
o noany
, usar una vista booleana significa manejar el cero negativo como desigual al cero regular.)Reformé la matriz y luego la iteré. Desafortunadamente, mi respuesta asume que tiene al menos tres dimensiones y generará un error para las matrices normales, tendría que agregar una cláusula especial para las matrices con forma de 1 y 2 dimensiones. Además, esto será lento, por lo que probablemente haya mejores soluciones.
Que producirá
Básicamente apilo todas las dimensiones una encima de la otra y luego miro a través de ellas para verificar sus bordes.
fuente
tal vez el operador de puntos suspensivos es lo que está buscando, que funcionará para muchas dimensiones:
fuente
Puede utilizar el
slice
enmascaramiento booleano para hacer el trabajo:Esta función primero da forma al "núcleo" de la matriz en la tupla
s
, y luego crea una máscara que se muestraTrue
solo para los puntos limítrofes. La indexación booleana entrega los puntos de borde.Ejemplo de trabajo:
Luego,
np.all(borders==0)
te dará la información deseada.Nota: esto se rompe para las matrices unidimensionales, aunque considero que son un caso extremo. Probablemente sea mejor que solo verifique los dos puntos en cuestión allí
fuente
np.arange(15)
no incluye 15.