2012-06-05 1 views
4

Comment exprimer efficacement ce qui suit en utilisant numexpr?Capper une sous-expression dans numexpr

z = min(x-y, 1.0)/(x+y) 

Ici, x et y sont quelques grands tableaux de numpy de la même forme.

En d'autres termes, j'essaie de plafonner x-y à 1.0 avant de le diviser par x+y.

je voudrais le faire en utilisant une seule expression numexpr (x et y sont énormes, et je ne veux pas avoir à itérer sur plus d'une fois).

+1

Pour être clair (parce que min (xy, 1) n'est pas numpy valide), voulez-vous plafonner xy à une borne supérieure de 1 avant de la diviser par (x + y)? – DSM

+0

@DSM: Oui, c'est précisément ce que j'essaie de faire. J'ai édité la question. – NPE

Répondre

6

Peut-être que quelque chose comme ça fonctionnerait?

In [11]: import numpy as np 
In [12]: import numexpr as ne  
In [13]:  
In [13]: x = np.linspace(0.02, 5.0, 1e7) 
In [14]: y = np.sin(x) 
In [15]:  
In [15]: timeit z0 = ((x-y) - ((x-y) > 1) * (x-y - 1))/(x+y) 
1 loops, best of 3: 1.02 s per loop 
In [16]: timeit z1 = ne.evaluate("((x-y) - ((x-y) > 1.) * ((x-y) - 1.))/(x+y)") 
10 loops, best of 3: 120 ms per loop  
In [17]: timeit z2 = ne.evaluate("((x-y)/(x+y))") 
10 loops, best of 3: 103 ms per loop 

Il y a une pénalité pour le recouvrement au-dessus de la division, mais ce n'est pas trop mauvais. Malheureusement, lorsque je l'ai essayé pour des tableaux plus grands, je me suis trompé. : -/

Mise à jour: ce qui est beaucoup plus jolie, et un peu plus rapide aussi:

In [40]: timeit w0 = ne.evaluate("where(x-y>1,1,x-y)/(x+y)") 
10 loops, best of 3: 114 ms per loop 
Questions connexes