Numpy vectorize comme un décorateur avec des arguments
j'ai essayé de vectoriser (d'accord, pas la façon la plus efficace de le faire, mais ma question est plutôt sur l'utilisation de décorateur) la fonction suivante
@np.vectorize
def diff_if_bigger(x, y):
return y - x if y > x else 0
x = np.array([5.6, 7.0])
y = 8
diff_if_bigger(x, y)
# outputs array([2, 1]) which is not what I want
EDIT: après avoir redémarré IPython, la sortie était correcte.
est-ce que quelqu'un peut expliquer pourquoi le résultat de diff_if_bigger
ont été transformés en un tableau de np.int
même si le premier argument x est ici un aray np.float
, contrairement à ce qu'il y a dans le doc????
Maintenant, je veux forcer une sortie float, donc Je l'ai fait
@np.vectorize('np.float')
def diff_if_bigger(x, y):
return y - x if y > x else 0
# Error !!
# TypeError: Object is not callable.
@np.vectorize(otypes='np.float')
def diff_if_bigger(x, y):
return y - x if y > x else 0
# Again error !!
# TypeError: __init__() takes at least 2 arguments (2 given)
@np.vectorize(otypes=[np.float])
def diff_if_bigger(x, y):
return y - x if y > x else 0
# Still an error !!
# TypeError: __init__() takes at least 2 arguments (2 given)
Par ailleurs, même cette
vec_diff = np.vectorize(diff_if_bigger, otypes=[np.float])
ne fonctionne pas!!! Alors que ce passe??
EDIT: en fait, ce dernier a fonctionné après que j'ai redémarré IPython.
donc après mes deux éditions précédentes, ma question est maintenant Double:
1 - Comment puis-je utiliser np.vectoriser un décorateur avec des arguments?
2 - Comment puis-je nettoyer IPython state?
1 réponses
Fonctionne pour moi:
>>> import numpy as np
>>> @np.vectorize
... def diff_if_bigger(x, y):
... return y - x if y > x else 0
...
>>> diff_if_bigger(np.array([5.6,7.0]), 8)
array([ 2.4, 1. ])
Notez que np.vectorize
n'est pas vraiment fait pour être décorateur sauf dans les cas les plus simples. Si vous avez besoin de spécifier explicitement otype
, utilisez la forme habituelle new_func = np.vectorize(old_func, otypes=...)
ou utiliser functools.partial
pour obtenir un décorateur.
Notez aussi que np.vectorize
, par défaut, obtient son type de sortie en évaluant la fonction sur le premier argument:
Le type de données de la sortie de
vectorized
est déterminé en appelant la fonction avec la première élément de l'entrée.
donc, vous devriez passer float
et retour float
si vous voulez vous assurer qu'il déduit float
comme la sortie dtype (par exemple utiliser else 0.0
et passer y = 8.0
).