python: cómo identificar si una variable es un array o un escalar


Tengo una función que toma el argumento NBins. Quiero hacer una llamada a esta función con un escalar 50 o un array [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?

He intentado 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 ves, no puedo aplicar len a P, ya que no es un array.... Hay algo como isarray o isscalar en python?

Gracias

Author: otmezger, 2013-05-29

10 answers

>>> isinstance([0, 10, 20, 30], list)
True
>>> isinstance(50, list)
False

Para soportar cualquier tipo de secuencia, marque collections.Sequence en lugar de list.

Nota: isinstance también soporta una tupla de clases, check type(x) in (..., ...) debe evitarse y es innecesario.

Es posible que también desee comprobar not isinstance(x, (str, unicode))

 263
Author: jamylak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-10 11:04:49

Las respuestas anteriores asumen 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:

if hasattr(N, "__len__")
 90
Author: jpaddison3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-04 17:32:06

Combinando las respuestas de @jamylak y @jpaddison3 juntas, si necesita ser robusto contra matrices numpy como entrada y manejarlas de la misma manera que las listas, debe usar{[15]]}

import numpy as np
isinstance(P, (list, tuple, np.ndarray))

Esto es robusto contra subclases de matrices list, tupla y numpy.

Y si desea ser robusto contra todas las demás subclases de secuencia también (no solo lista y tupla), use

import collections
import numpy as np
isinstance(P, (collections.Sequence, np.ndarray))

¿Por qué hacer las cosas de esta manera con isinstance y no comparar type(P) con un valor objetivo? Aquí hay un ejemplo, donde hacemos y estudiamos el comportamiento de NewList, una subclase trivial de list.

>>> class NewList(list):
...     isThisAList = '???'
... 
>>> x = NewList([0,1])
>>> y = list([0,1])
>>> print x
[0, 1]
>>> print y
[0, 1]
>>> x==y
True
>>> type(x)
<class '__main__.NewList'>
>>> type(x) is list
False
>>> type(y) is list
True
>>> type(x).__name__
'NewList'
>>> isinstance(x, list)
True

A pesar de que x y y se comparen como iguales, manejarlos por type resultaría en un comportamiento diferente. Sin embargo, dado que x es una instancia de una subclase de list, usar isinstance(x,list) da el comportamiento deseado y trata x y y de la misma manera.

 28
Author: scottclowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-02 16:29:26

¿Hay un equivalente a isscalar() en numpy? Sí.

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True
 20
Author: jmhl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-13 04:53:17

Si bien el enfoque de @jamylak es el mejor, aquí hay un enfoque alternativo

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True
 13
Author: Sukrit Kalra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 06:37:21

Otro enfoque alternativo (uso de la clase nombre propiedad):

N = [2,3,5]
P = 5

type(N).__name__ == 'list'
True

type(P).__name__ == 'int'
True

type(N).__name__ in ('list', 'tuple')
True

No hay necesidad de importar nada.

 3
Author: Marek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 07:13:58

Simplemente use size en lugar de len!

>>> from numpy import size
>>> N = [2, 3, 5]
>>> size(N)
3
>>> N = array([2, 3, 5])
>>> size(N)
3
>>> P = 5
>>> size(P)
1
 3
Author: Mathieu Villion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-04 09:56:40
>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False
 2
Author: simple_human,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 06:40:59

Puede comprobar el tipo de datos de la variable.

N = [2,3,5]
P = 5
type(P)

Se le dará a cabo poner como tipo de datos de P.

<type 'int'>

Para que pueda diferenciar que es un entero o una matriz.

 2
Author: unnati patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 06:54:11

Me sorprende que una pregunta tan básica no parezca tener una respuesta inmediata en python. Me parece que casi todas las respuestas propuestas utilizan algún tipo de tipo comprobación, que generalmente no se aconseja en python y parecen restringidos a un caso específico (fallan con diferentes tipos numéricos u objetos iterables genéricos que no son tuplas o listas).

Para mí, lo que funciona mejor es importar numpy y usar array.tamaño, por ejemplo:

>>> a=1
>>> np.array(a)
Out[1]: array(1)

>>> np.array(a).size
Out[2]: 1

>>> np.array([1,2]).size
Out[3]: 2

>>> np.array('125')
Out[4]: 1

Nota también:

>>> len(np.array([1,2]))

Out[5]: 2

Pero:

>>> len(np.array(a))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-40-f5055b93f729> in <module>()
----> 1 len(np.array(a))

TypeError: len() of unsized object
 1
Author: Vincenzooo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-29 16:35:52