Tengo una función que toma el argumento NBins
. Quiero hacer una llamada a esta función con un escalar 50
o una matriz [0, 10, 20, 30]
. ¿Cómo puedo identificar dentro de la función, cuál es la longitud de NBins
? o dicho de otra manera, si es un escalar o un vector?
Intenté esto:
>>> 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 se puede ver, no puedo aplicar len
a P
, ya que no es una matriz .... ¿Hay algo así como isarray
o isscalar
en Python?
Gracias
type
?Respuestas:
Para admitir cualquier tipo de secuencia, marque en
collections.Sequence
lugar delist
.nota :
isinstance
también admite una tupla de clases, setype(x) in (..., ...)
debe evitar la comprobación y es innecesario.También es posible que desee comprobar
not isinstance(x, (str, unicode))
fuente
list
para obtener falsos para escalares ... graciascollections.Sequence
es un ABC para cadena, por lo que debe tenerse en cuenta. Estoy usando algo asíif type(x) is not str and isinstance(x, collections.Sequence):
. Esto no es genial, pero es confiable.type
, y también verifiquenot isinstance(x, (str, unicode))
Python 2Las respuestas anteriores suponen que la matriz es una lista estándar de Python. Como alguien que usa numpy a menudo, recomendaría una prueba muy pitónica de:
fuente
__len__
atributo (así que supongo que técnicamente no es un tipo escalar)if hasattr(N, '__len__') and (not isinstance(N, str))
explicaría adecuadamente las cadenas.Combinando las respuestas de @jamylak y @ jpaddison3 juntas, si necesita ser robusto frente a matrices numpy como entrada y manejarlas de la misma manera que las listas, debe usar
Esto es robusto frente a subclases de listas, tuplas y matrices numpy.
Y si también quiere ser robusto frente a todas las demás subclases de secuencia (no solo lista y tupla), use
¿Por qué debería hacer las cosas de esta manera
isinstance
y no compararlastype(P)
con un valor objetivo? Aquí hay un ejemplo, donde hacemos y estudiamos el comportamiento deNewList
una subclase trivial de la lista.A pesar de
x
yy
comparándolos como iguales, manejarlos con ellostype
resultaría en un comportamiento diferente. Sin embargo, ya quex
es una instancia de una subclase delist
, utilizandoisinstance(x,list)
da el comportamiento y trata deseadox
yy
de la misma manera.fuente
isinstance(P, (list, tuple, set, np.ndarray))
¿Hay un equivalente a isscalar () en numpy? Si.
fuente
>>> np.isscalar('abcd')
devolucionesTrue
.return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
numpy.isscalar()
función sufre una serie de defectos de diseño irreconciliables y probablemente quedará obsoleta en alguna revisión futura. Parafraseando la documentación oficial : "En casi todos los casos senp.ndim(x) == 0
debe usar en lugar denp.isscaler(x)
, ya que el primero también devolverá correctamente verdadero para las matrices 0d". Una sólida alternativa compatible con interésnumpy.isscalar()
lo tanto, sería trivial para envolvernumpy.ndim()
: por ejemplo,def is_scalar(obj): return np.ndim(obj) == 0
np.isscalar
es confuso. El documento oficial sugirió usarlo ennp.array.ndim
todas partes,np.isscalar(np.array(12))
es decir, es falso, aunque debería considerarse escalar, ya quenp.array(12).ndim
es 0.Mientras que el enfoque de @ jamylak es el mejor, aquí hay un enfoque alternativo
fuente
type(p) in (list, )
.Otro enfoque alternativo (uso de la propiedad de nombre de clase ):
No es necesario importar nada.
fuente
Aquí está el mejor enfoque que he encontrado: Verifique la existencia de
__len__
y__getitem__
.Usted puede preguntar por qué? Los motivos incluyen:
isinstance(obj, abc.Sequence)
falla en algunos objetos, incluido el Tensor de PyTorch porque no se implementan__contains__
.__len__
y__getitem__
que considero que son métodos mínimos para objetos tipo matriz.Así que sin más preámbulos:
Tenga en cuenta que he agregado parámetros predeterminados porque la mayoría de las veces es posible que desee considerar las cadenas como valores, no como matrices. Del mismo modo para las tuplas.
fuente
fuente
Puede verificar el tipo de datos de la variable.
Le dará salida como tipo de datos de P.
Para que pueda diferenciar que es un entero o una matriz.
fuente
Me sorprende que una pregunta tan básica no parezca tener una respuesta inmediata en Python. Me parece que casi todas las respuestas propuestas usan algún tipo de verificación de tipo, que generalmente no se recomienda en python y parecen restringidas a un caso específico (fallan con diferentes tipos numéricos u objetos genéricos iterables que no son tuplas o listas).
Para mí, lo que funciona mejor es importar numpy y usar array.size, por ejemplo:
Nota también:
pero:
fuente
Simplemente use en
size
lugar delen
!fuente
np.size(5)
ynp.size([5])
son ambos ==1
, por lo que esto no distingue correctamente el tipo (es decir, identifica un escalar), que creo que es el objetivo.preds_test [0] tiene forma (128,128,1) Permite verificar su tipo de datos usando la función isinstance () La función isinstance toma 2 argumentos. El primer argumento es datos. El segundo argumento es tipo de datos isinstance (preds_test [0], np.ndarray) da la salida como Verdadero. Significa que preds_test [0] es una matriz.
fuente
Para responder la pregunta en el título, una forma directa de saber si una variable es escalar es intentar convertirla en flotante. Si lo consigues
TypeError
, no lo es.fuente