Eu tenho uma função que aceita o argumento NBins
. Quero fazer uma chamada para essa função com um escalar 50
ou uma matriz [0, 10, 20, 30]
. Como posso identificar dentro da função, qual é o tamanho NBins
? ou dito de forma diferente, se for um escalar ou um vetor?
Eu tentei isso:
>>> N=[2,3,5]
>>> P = 5
>>> len(N)
3
>>> len(P)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
>>>
Como você pode ver, eu não posso aplicar len
para P
, uma vez que não é um array .... Existe algo parecido isarray
ou isscalar
em python?
obrigado
type
?Respostas:
Para suportar qualquer tipo de sequência, marque em
collections.Sequence
vez delist
.nota :
isinstance
também suporta uma tupla de classes, a verificaçãotype(x) in (..., ...)
deve ser evitada e é desnecessária.Você também pode querer verificar
not isinstance(x, (str, unicode))
fonte
list
para obter false para escalares ... obrigadocollections.Sequence
é um ABC para string, portanto, isso deve ser levado em consideração. Estou usando algo parecidoif type(x) is not str and isinstance(x, collections.Sequence):
. Isso não é ótimo, mas é confiável.type
, e também verificarnot isinstance(x, (str, unicode))
em Python 2As respostas anteriores assumem que a matriz é uma lista padrão do python. Como alguém que usa sonolento com frequência, eu recomendaria um teste muito pythonico de:
fonte
__len__
atributo (então eu acho, não é tecnicamente um tipo escalar)if hasattr(N, '__len__') and (not isinstance(N, str))
seria responsável por seqüências de caracteres.Combinando as respostas @jamylak e @ jpaddison3, se você precisar ser robusto com matrizes numpy como entrada e manipulá-las da mesma maneira que as listas, use
Isso é robusto contra subclasses de matrizes de lista, tupla e numpy.
E se você quiser ser robusto com todas as outras subclasses de sequência (não apenas lista e tupla), use
Por que você deve fazer as coisas dessa maneira
isinstance
e não comparartype(P)
com um valor-alvo? Aqui está um exemplo, onde criamos e estudamos o comportamento deNewList
, uma subclasse trivial da lista.Apesar
x
ey
comparando como iguais, lidar com elestype
resultaria em um comportamento diferente. No entanto, uma vez quex
é uma instância de uma subclasse delist
, usingisinstance(x,list)
fornece o comportamento e os tratamentos desejadosx
ey
da mesma maneira.fonte
isinstance(P, (list, tuple, set, np.ndarray))
Existe um equivalente a isscalar () em numpy? Sim.
fonte
>>> np.isscalar('abcd')
retornaTrue
.return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
numpy.isscalar()
função sofre várias falhas irreconciliáveis de design e provavelmente será preterida em alguma revisão futura. Parafraseando a documentação oficial : "Em quase todos os casos,np.ndim(x) == 0
deve ser usado em vez denp.isscaler(x)
, pois o primeiro também retornará corretamente true para matrizes 0d". Uma alternativa para a frente-compatível robusto paranumpy.isscalar()
seria, assim, para embrulhar trivialmentenumpy.ndim()
: por exemplo,def is_scalar(obj): return np.ndim(obj) == 0
np.isscalar
é confuso. Doc oficial sugeriu o uso denp.array.ndim
todos os lugares, ou seja,np.isscalar(np.array(12))
é False enquanto ele deve ser considerado como escalar uma veznp.array(12).ndim
é 0.Embora a abordagem do @ jamylak seja a melhor, aqui está uma abordagem alternativa
fonte
type(p) in (list, )
.Outra abordagem alternativa (uso da propriedade do nome da classe ):
Não há necessidade de importar nada.
fonte
Aqui está a melhor abordagem que eu encontrei: Verifique a existência de
__len__
e__getitem__
.Você pode perguntar por quê? Os motivos incluem:
isinstance(obj, abc.Sequence)
falha em alguns objetos, incluindo o Tensor do PyTorch, porque eles não são implementados__contains__
.__len__
e__getitem__
que considero métodos mínimos para objetos do tipo array.Portanto, sem mais delongas:
Observe que eu adicionei parâmetros padrão, porque na maioria das vezes você pode considerar cadeias de caracteres como valores, não matrizes. Da mesma forma para tuplas.
fonte
fonte
Você pode verificar o tipo de dados da variável.
Ele fornecerá o tipo de dados P.
Para que você possa diferenciar que é um número inteiro ou uma matriz.
fonte
Estou surpreso que uma pergunta tão básica não pareça ter uma resposta imediata em python. Parece-me que quase todas as respostas propostas usam algum tipo de verificação de tipo, que geralmente não é recomendada em python e parecem restritas a um caso específico (elas falham com tipos numéricos diferentes ou objetos iteráveis genéricos que não são tuplas ou listas).
Para mim, o que funciona melhor é importar numpy e usar array.size, por exemplo:
Observe também:
mas:
fonte
Basta usar em
size
vez delen
!fonte
np.size(5)
enp.size([5])
são ambos ==1
, portanto, isso não distingue corretamente o tipo (ou seja, identifica um escalar), que acredito ser o objetivo.preds_test [0] é da forma (128,128,1) Permite verificar seu tipo de dados usando a função isinstance () isinstance recebe 2 argumentos. O 1º argumento é dados O 2º argumento é o tipo de dados isinstance (preds_test [0], np.ndarray) fornece Output como True. Isso significa que o preds_test [0] é uma matriz.
fonte
Para responder à pergunta no título, uma maneira direta de saber se uma variável é escalar é tentar convertê-la em um ponto flutuante. Se você conseguir
TypeError
, não é.fonte