2013-02-20 14 views
5

ho cercato di vettorizzare (concordato, non è il modo più efficace per farlo, ma la mia domanda è piuttosto sull'uso decoratore) la seguente funzioneNumpy vectorize come decoratore con argomenti

@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: Dopo aver riavviato IPython, l'output era OK.

qualcuno può spiegare il motivo per cui il risultato di diff_if_bigger ottenuto tansformed in un array di np.int, anche se il primo argomento x è qui un aray di np.float, contrariamente a ciò che è nel doc ????

Ora, voglio forzare un'uscita galleggiante, così ho fatto questo

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

Tra l'altro, anche questo

vec_diff = np.vectorize(diff_if_bigger, otypes=[np.float]) 

non funziona !!! Quindi cosa sta succedendo ??

EDIT: In effetti, quest'ultimo ha funzionato dopo il riavvio di IPython.

Così, dopo i miei due precedenti modifiche, la mia domanda è ora duplice:

1- Come posso usare np.vectorize come decoratore con argomenti?

2- Come posso pulire lo stato di IPython?

+0

@seberg, no, stai dicendo sciocchezze .. –

+0

Guarda, davvero non rispondi in modo specifico a nessuna delle mie domande .. Hai mai provato a eseguire i bit di codice che ho postato ??? Hai guardato l'aiuto vectorize ?? –

+0

Siamo spiacenti, ma forse dovresti fornire descrizioni degli errori migliori, è un po 'difficile da diagnosticare in questo modo. 1. Tutti i tuoi esempi funzionano effettivamente (ma quelli decoratori danno un tipo, che non può). 2. Il tuo primo esempio potrebbe fallire, se hai dato un input diverso prima di quell'input. 3. L'ultima chiamata vettoriale su una funzione che è già vettorizzata non ha senso, quindi forse questo è il tuo inquietante "non funziona". – seberg

risposta

7

funziona per me:

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

Nota che np.vectorize non è veramente destinata come decoratore fatta eccezione per i casi più semplici. Se è necessario specificare un esplicito otype, utilizzare il modulo usuale new_func = np.vectorize(old_func, otypes=...) o utilizzare functools.partial per ottenere un decoratore.

Nota anche che np.vectorize, per default, prende il tipo di uscita a valutare la funzione sul primo argomento:

Il tipo di dati dell'uscita del vectorized è determinata chiamando la funzione con il primo elemento di l'input.

Quindi, si dovrebbe passare float e tornare float se si vuole assicurare che deduce float come DTYPE uscita (ad esempio utilizzare else 0.0 e passare y = 8.0).

+0

La mia versione numpy è la 1.6.1 .. e non ho lo stesso comportamento del rapporto, ma quello che ho menzionato nel mio post. Nel mio caso, il primo input x è un array di 'np.float', quindi perché ottengo un array di' np.int' alla fine ?? Ma peggio, come ho detto nel mio OP, ho avuto errori anche se non avessi usato np.vectorize come decoratore !! –

+1

non è il primo "input" che conta, ma il primo "output" e 0 non è un float. – seberg

+0

@nneonneo Ho paura che il comportamento che ho ottenuto sia dovuto allo stato interno della mia sessione IPython. Ma poi, non riesco a capire perché quella sessione è stata corrotta al punto in cui il file np.vectorize non si comportava come annunciato nei documenti. –

Problemi correlati