Pergunta

Com certeza uma matriz 0d é escalar, mas não Numpy não parecem pensar assim ... estou faltando alguma coisa ou estou apenas mal-entendido o conceito?

>>> foo = numpy.array(1.11111111111, numpy.float64)
>>> numpy.ndim(foo)
0
>>> numpy.isscalar(foo)
False
>>> foo.item()
1.11111111111
Foi útil?

Solução

Não se deve pensar muito sobre isso. É, em última análise melhor para a saúde mental e longevidade do indivíduo.

A situação curiosa com Numpy escalares tipos era furo fora do fato de que não há nenhuma maneira graciosa e consistente para degradar a matriz 1x1 para tipos escalares. Mesmo que matematicamente são a mesma coisa, eles são manipulados por código muito diferente.

Se você tem feito qualquer quantidade de código científica, em última análise, você iria querer coisas como max(a) ao trabalho em matrizes de todos os tamanhos, até mesmo escalares. Matematicamente, isso é uma coisa perfeitamente razoável esperar. No entanto, para os programadores Isso significa que tudo o que apresenta escalares em Numpy deve ter o .shape e attirbute .ndim, assim, pelo menos os ufuncs não tem que fazer a verificação de tipo explícitas à sua entrada para os 21 tipos escalares possíveis em Numpy.

Por outro lado, eles também deve trabalhar com bibliotecas Python existentes que faz do tipo verifica-explícitas tipo escalar. Este é um dilema, uma vez que um Numpy ndarray tem que mudar individualmente seu tipo quando eles foram reduzidos a um escalar, e não há nenhuma maneira de saber se isso ocorreu sem que tenha fazer verificações em todos os acessos. Realmente ir por esse caminho provavelmente faria pouco ridiculamente lento para trabalhar com os padrões tipo escalar.

A solução do desenvolvedor Numpy é herdar de ambos ndarray e escalares Python para seu próprio tipo scalary, de modo que todos os escalares também têm .shape, .ndim, T., etc etc. A matriz 1x1 ainda vai estar lá, mas a sua uso será desencorajado se você sabe que você estará lidando com um escalar. Enquanto isso deve funcionar bem em teoria, ocasionalmente, você ainda pode ver alguns lugares onde eles perderam com o rolo de pintura, e as entranhas feias são expostas para que todos vejam:

>>> from numpy import *
>>> a = array(1)
>>> b = int_(1)
>>> a.ndim
0
>>> b.ndim
0
>>> a[...]
array(1)
>>> a[()]
1
>>> b[...]
array(1)
>>> b[()]
1

Não há realmente nenhuma razão para que a[...] e a[()] deve retornar coisas diferentes, mas ele faz. Há propostas em lugar de alterar este, mas parece que se esqueceram de terminar o trabalho para 1x1 matrizes.

A potencialmente maior, e possivelmente não resolvido problema, é o fato de que escalares Numpy são imutáveis. Portanto "pulverização" um escalar em um ndarray, matematicamente a operação adjunta de colapso uma matriz em um escalar, é um PITA de implementar. Você não pode realmente crescer um escalar Numpy, não pode, por definição, ser lançado um ndarray, embora newaxis misteriosamente trabalha nele:

>>> b[0,1,2,3] = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'numpy.int32' object does not support item assignment
>>> b[newaxis]
array([1])

Em Matlab, aumentar o tamanho de um escalar é uma operação perfeitamente aceitável e sem cérebro. Em Numpy você tem que ficar rangendo a = array(a) em todos os lugares você pensar você tem a possibilidade de começar com um escalar e terminando com uma série. Eu entendo porque Numpy tem que ser dessa maneira para jogar bonito com Python, mas isso não muda o fato de que muitos novos switchers estão profundamente confuso sobre isso. Alguns têm memória explícita de lutar com esse comportamento e, eventualmente, perseverante, enquanto outros que estão muito longe são geralmente deixadas com alguma cicatriz mental, disforme profunda que freqüentemente assombra seus sonhos mais inocente. É uma situação horrível para todos.

Outras dicas

Você tem que criar a matriz escalar um pouco diferente:

>>> x = numpy.float64(1.111)
>>> x
1.111
>>> numpy.isscalar(x)
True
>>> numpy.ndim(x)
0

Parece que escalares em numpy pode ser um pouco conceito diferente do que você pode ser usado para a partir de um ponto de vista puramente matemático. Eu estou supondo que você está pensando em termos de matricies escalares?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top