Qual seria a maneira mais rápida de verificar se uma matriz numpy multidimensional tem 0 em todos os lados.
Então, para um exemplo 2D simples, tenho:
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
Embora isso seja bom para casos 2D corretos, escrever para dimensões mais altas é um pouco entediante e eu queria saber se existe algum truque inteligente e inteligente que eu possa usar aqui para torná-lo eficiente e também mais sustentável.
np.all (x[:, 0] == 0)
seria mais seguro que a soma? O teste de soma está correto apenas se todos os números forem positivos.Respostas:
Veja como você pode fazer isso:
np.take
faz o mesmo que indexação "sofisticada".fonte
numpy.take
faz uma cópia. Isso pode causar um desempenho pior que o código com base em uma exibição. (O tempo seria necessário para ter certeza - a eficiência da exibição do NumPy às vezes é estranha.)len(x.shape)
pode ser escrito de forma mais simples comox.ndim
.all
curto-circuitos. Você pode remover os colchetes para usar uma expressão de gerador, permitindoall
retornar assim que uma únicanumpy.all
chamada retornarFalse
.Aqui está uma resposta que realmente examina as partes da matriz em que você está interessado e não perde tempo construindo uma máscara do tamanho de toda a matriz. Há um loop no nível do Python, mas é curto, com iterações proporcionais ao número de dimensões em vez do tamanho da matriz.
fonte
not (view[0] == 0).all()
não é equivalenteview[0].any()
?view[0].any()
que funcionaria também. Não tenho muita certeza das implicações de eficiência da conversão e do buffer envolvidas nas duas opções -view[0].any()
teoricamente poderiam ser implementadas mais rapidamente, mas já vi resultados estranhos antes e não compreendo completamente o buffer envolvido.view[0].view(bool).any()
que seria a solução de alta velocidade.argmax
pode realmente superarany
a visão booleana . Esse material fica estranho.argmax
ouany
, usar uma visualização booleana significa manipular o zero negativo como desigual ao zero regular.)Alterei a forma da matriz e iteramos através dela. Infelizmente, minha resposta pressupõe que você tenha pelo menos três dimensões e irá errar em matrizes normais; você teria que adicionar uma cláusula especial para matrizes de 1 e 2 dimensões. Além disso, isso será lento, portanto provavelmente haverá melhores soluções.
Qual produzirá
Basicamente, empilho todas as dimensões umas sobre as outras e olho através delas para verificar suas bordas.
fonte
talvez o operador de reticências seja o que você está procurando, que funcionará em várias dimensões:
fonte
Você pode usar o
slice
mascaramento booleano para realizar o trabalho:Essa função primeiro molda o "núcleo" da matriz na tupla
s
e depois cria uma máscara que é exibidaTrue
apenas para os pontos limítrofes. A indexação booleana entrega os pontos de borda.Exemplo de trabalho:
Então,
np.all(borders==0)
você fornecerá as informações desejadas.Nota: isso quebra para matrizes unidimensionais, embora eu as considere um caso extremo. Você provavelmente está melhor apenas verificando os dois pontos em questão
fonte
np.arange(15)
não inclui 15.