Comment déterminer de manière fiable si un objet a un type numpy?
Je me rends compte que cette question va à l’encontre de la philosophie de la dactylographie, mais l’idée est de s’assurer qu’une fonction (qui utilise scipy et numpy) ne renvoie jamais un type numpy à moins d’être appelée avec un type numpy. Cela revient dans la solution à une autre question, mais je pense que le problème général de déterminer si un objet a un type numpy est suffisamment éloigné de la question initiale pour pouvoir être séparé.
Utilisez la fonction intégrée type
pour obtenir le type, puis utilisez la fonction __module__
propriété pour savoir où elle a été définie:
>>> import numpy as np
a = np.array([1, 2, 3])
>>> type(a)
<type 'numpy.ndarray'>
>>> type(a).__module__
'numpy'
>>> type(a).__module__ == np.__name__
True
La solution que j'ai trouvée est:
isinstance(y, (np.ndarray, np.generic) )
Cependant, ce n'est pas clair à 100% que tous les types numpy sont garantis d'être soit np.ndarray
ou np.generic
, et ce n'est probablement pas la version robuste.
Vieille question mais je suis venu avec une réponse définitive avec un exemple. Je ne peux pas nuire à la fraîcheur des questions car j'avais le même problème et je n'ai pas trouvé de réponse claire. La clé est de vous assurer que vous avez importé numpy
, puis exécutez le isinstance
bool. Bien que cela puisse sembler simple, si vous effectuez des calculs sur différents types de données, cette petite vérification peut servir de test rapide avant de commencer une opération numpy vectorisée.
##################
# important part!
##################
import numpy as np
####################
# toy array for demo
####################
arr = np.asarray(range(1,100,2))
########################
# The instance check
########################
isinstance(arr,np.ndarray)
Pour obtenir le type, utilisez la fonction intégrée type
. Avec l'opérateur in
, vous pouvez vérifier si le type est un type numpy en vérifiant s'il contient la chaîne numpy
;
In [1]: import numpy as np
In [2]: a = np.array([1, 2, 3])
In [3]: type(a)
Out[3]: <type 'numpy.ndarray'>
In [4]: 'numpy' in str(type(a))
Out[4]: True
(Cet exemple a été exécuté dans IPython , à propos. Très pratique pour une utilisation interactive et des tests rapides.)
Cela dépend en fait de ce que vous recherchez.
ndarray
, une isinstance(..., np.ndarray)
est probablement la plus simple. Assurez-vous de ne pas recharger numpy en arrière-plan car le module peut être différent, mais sinon, tout devrait bien se passer. MaskedArrays
, matrix
, recarray
sont tous des sous-classes de ndarray
, vous devriez donc être défini.shape
et un attribut dtype
. Vous pouvez comparer ses dtype
aux types de base, dont vous pouvez trouver la liste dans np.core.numerictypes.genericTypeRank
. Notez que les éléments de cette liste sont des chaînes, vous devriez donc faire un tested.dtype is np.dtype(an_element_of_the_list)
...Notez que la type(numpy.ndarray)
est un type
lui-même et faites attention aux types booléens et scalaires. Ne soyez pas trop découragé si ce n’est pas intuitif ou facile, c’est pénible au début.
Voir aussi: - https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.dtypes.html - https://github.com/machinalis/mypy-data/tree/master/numpy-mypy
>>> import numpy as np
>>> np.ndarray
<class 'numpy.ndarray'>
>>> type(np.ndarray)
<class 'type'>
>>> a = np.linspace(1,25)
>>> type(a)
<class 'numpy.ndarray'>
>>> type(a) == type(np.ndarray)
False
>>> type(a) == np.ndarray
True
>>> isinstance(a, np.ndarray)
True
Fun avec des booléens:
>>> b = a.astype('int32') == 11
>>> b[0]
False
>>> isinstance(b[0], bool)
False
>>> isinstance(b[0], np.bool)
False
>>> isinstance(b[0], np.bool_)
True
>>> isinstance(b[0], np.bool8)
True
>>> b[0].dtype == np.bool
True
>>> b[0].dtype == bool # python equivalent
True
Plus de plaisir avec les types scalaires, voir: - https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.scalars.html#arrays-scalars-built-in
>>> x = np.array([1,], dtype=np.uint64)
>>> x[0].dtype
dtype('uint64')
>>> isinstance(x[0], np.uint64)
True
>>> isinstance(x[0], np.integer)
True # generic integer
>>> isinstance(x[0], int)
False # but not a python int in this case
# Try matching the `kind` strings, e.g.
>>> np.dtype('bool').kind
'b'
>>> np.dtype('int64').kind
'i'
>>> np.dtype('float').kind
'f'
>>> np.dtype('half').kind
'f'
# But be weary of matching dtypes
>>> np.integer
<class 'numpy.integer'>
>>> np.dtype(np.integer)
dtype('int64')
>>> x[0].dtype == np.dtype(np.integer)
False
# Down these paths there be dragons:
# the .dtype attribute returns a kind of dtype, not a specific dtype
>>> isinstance(x[0].dtype, np.dtype)
True
>>> isinstance(x[0].dtype, np.uint64)
False
>>> isinstance(x[0].dtype, np.dtype(np.uint64))
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: isinstance() arg 2 must be a type or Tuple of types
# yea, don't go there
>>> isinstance(x[0].dtype, np.int_)
False # again, confusing the .dtype with a specific dtype
# Inequalities can be tricky, although they might
# work sometimes, try to avoid these idioms:
>>> x[0].dtype <= np.dtype(np.uint64)
True
>>> x[0].dtype <= np.dtype(np.float)
True
>>> x[0].dtype <= np.dtype(np.half)
False # just when things were going well
>>> x[0].dtype <= np.dtype(np.float16)
False # oh boy
>>> x[0].dtype == np.int
False # ya, no luck here either
>>> x[0].dtype == np.int_
False # or here
>>> x[0].dtype == np.uint64
True # have to end on a good note!