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?

8
demandé sur green diod 2013-02-20 21:56:33

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).

9
répondu nneonneo 2013-02-20 18:02:59