Tengo una función que toma el argumento NBins. Quiero hacer una llamada a esta función con un escalar 50o 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 lena P, ya que no es una matriz .... ¿Hay algo así como isarrayo isscalaren Python?
Gracias

type?Respuestas:
Para admitir cualquier tipo de secuencia, marque en
collections.Sequencelugar delist.nota :
isinstancetambié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
listpara obtener falsos para escalares ... graciascollections.Sequencees 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
isinstancey no compararlastype(P)con un valor objetivo? Aquí hay un ejemplo, donde hacemos y estudiamos el comportamiento deNewListuna subclase trivial de la lista.A pesar de
xyycomparándolos como iguales, manejarlos con ellostyperesultaría en un comportamiento diferente. Sin embargo, ya quexes una instancia de una subclase delist, utilizandoisinstance(x,list)da el comportamiento y trata deseadoxyyde 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) == 0debe 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) == 0np.isscalares confuso. El documento oficial sugirió usarlo ennp.array.ndimtodas partes,np.isscalar(np.array(12))es decir, es falso, aunque debería considerarse escalar, ya quenp.array(12).ndimes 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
sizelugar 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