python - transpuesta - numpy tutorial español pdf
Identificar tipos numéricos y de matriz en numpy (5)
¿Hay una función existente en numpy que me dirá si un valor es un tipo numérico o una matriz numpy? Estoy escribiendo un código de procesamiento de datos que necesita manejar números en varias representaciones diferentes (por "número" quiero decir cualquier representación de una cantidad numérica que pueda ser manipulada usando los operadores aritméticos estándar, +, -, *, /, * *).
Algunos ejemplos del comportamiento que estoy buscando
>>> is_numeric(5)
True
>>> is_numeric(123.345)
True
>>> is_numeric(''123.345'')
False
>>> is_numeric(decimal.Decimal(''123.345''))
True
>>> is_numeric(True)
False
>>> is_numeric([1, 2, 3])
False
>>> is_numeric([1, ''2'', 3])
False
>>> a = numpy.array([1, 2.3, 4.5, 6.7, 8.9])
>>> is_numeric(a)
True
>>> is_numeric(a[0])
True
>>> is_numeric(a[1])
True
>>> is_numeric(numpy.array([numpy.array([1]), numpy.array([2])])
True
>>> is_numeric(numpy.array([''1''])
False
Si no existe tal función, sé que no debería ser difícil escribir una, algo así como
isinstance(n, (int, float, decimal.Decimal, numpy.number, numpy.ndarray))
pero ¿hay otros tipos numéricos que deba incluir en la lista?
En general, la forma flexible, rápida y pitónica de manejar tipos desconocidos es simplemente realizar alguna operación sobre ellos y capturar una excepción en tipos no válidos.
try:
a = 5+''5''
except TypeError:
print "Oops"
Me parece que este enfoque es más fácil que especial: descartar alguna función para determinar la certeza absoluta del tipo.
Tu is_numeric
está mal definido. Vea mis comentarios a su pregunta.
Otros tipos numéricos podrían ser: long
, complex
, fractions.Fraction
. fractions.Fraction
, numpy.bool_
, numpy.ubyte
, ...
operator.isNumberType()
devuelve True
para los números de Python y numpy.array
.
Desde Python 2.6 puede usar isinstance(d, numbers.Number)
lugar de depreciar operator.isNumberType()
.
En general, es mejor verificar las capacidades del objeto (por ejemplo, si puede agregar un número entero) y no su tipo.
isinstance(numpy.int32(4), numbers.Number)
devuelve False
, por lo que no funciona. operator.isNumberType()
funciona en todas las variantes de números numpy, sin embargo, incluido numpy.array([1])
.
Además, numpy tiene numpy.isreal
y otras funciones similares ( numpy.is
+ Tab debería listarlas).
Todos tienen sus casos de esquina divertidos, pero uno de ellos podría ser útil.
Como otros han respondido, podría haber otros tipos numéricos además de los que mencionas. Un enfoque sería verificar explícitamente las capacidades que desea, con algo como
# Python 2
def is_numeric(obj):
attrs = [''__add__'', ''__sub__'', ''__mul__'', ''__div__'', ''__pow__'']
return all(hasattr(obj, attr) for attr in attrs)
# Python 3
def is_numeric(obj):
attrs = [''__add__'', ''__sub__'', ''__mul__'', ''__truediv__'', ''__pow__'']
return all(hasattr(obj, attr) for attr in attrs)
Esto funciona para todos sus ejemplos, excepto el último, numpy.array([''1''])
. Eso es porque numpy.ndarray
tiene los métodos especiales para operaciones numéricas, pero plantea TypeError si intenta utilizarlos de forma inapropiada con matrices de cadenas o de objetos. Puede agregar una verificación explícita para esto como
... and not (isinstance(obj, ndarray) and obj.dtype.kind in ''OSU'')
Esto puede ser lo suficientemente bueno.
Pero ... nunca se puede estar 100% seguro de que alguien no definirá otro tipo con el mismo comportamiento, por lo que una forma más infalible es intentar hacer un cálculo y detectar la excepción, algo así como
def is_numeric_paranoid(obj):
try:
obj+obj, obj-obj, obj*obj, obj**obj, obj/obj
except ZeroDivisionError:
return True
except Exception:
return False
else:
return True
pero dependiendo de la frecuencia con la que planee llamar, úsela y con qué argumentos, esto puede no ser práctico (puede ser potencialmente lento, por ejemplo, con arreglos grandes).