W takich przypadkach, masking
pomaga -
def mask_vectorized_app(x):
out = np.empty_like(x)
mask = x>=0
mask_rev = ~mask
out[mask] = np.log(x[mask]+1)
out[mask_rev] = -np.log(-x[mask_rev]+1)
return out
Przedstawiamy numexpr
module pomaga nam dalej.
import numexpr as ne
def mask_vectorized_numexpr_app(x):
out = np.empty_like(x)
mask = x>=0
mask_rev = ~mask
x_masked = x[mask]
x_rev_masked = x[mask_rev]
out[mask] = ne.evaluate('log(x_masked+1)')
out[mask_rev] = ne.evaluate('-log(-x_rev_masked+1)')
return out
Zainspirowany @user2685079's post
a następnie za pomocą właściwości logarithmetic: log(A**B) = B*log(A)
możemy wcisnąć Zapisz się do obliczeń dziennika, a to pozwala nam wykonać więcej pracy z numexpr
„s oceny ekspresji, tak jak -
s = (-2*(x<0))+1 # np.sign(x)
out = ne.evaluate('log((abs(x)+1)**s)')
Computing sign
stosując porównanie daje nam s
w inny sposób -
s = (-2*(x<0))+1
Wreszcie możemy pchnąć to do numexpr
oceny ekspresji -
def mask_vectorized_numexpr_app2(x):
return ne.evaluate('log((abs(x)+1)**((-2*(x<0))+1))')
testu Runtime
Loopy podejście do porównania -
def loopy_app(x):
out = np.empty_like(x)
for i in range(len(out)):
out[i] = f(x[i])
return out
synchronizacją czasową i weryfikacji -
In [141]: x = np.random.randn(100000)
...: print np.allclose(loopy_app(x), mask_vectorized_app(x))
...: print np.allclose(loopy_app(x), mask_vectorized_numexpr_app(x))
...: print np.allclose(loopy_app(x), mask_vectorized_numexpr_app2(x))
...:
True
True
True
In [142]: %timeit loopy_app(x)
...: %timeit mask_vectorized_numexpr_app(x)
...: %timeit mask_vectorized_numexpr_app2(x)
...:
10 loops, best of 3: 108 ms per loop
100 loops, best of 3: 3.6 ms per loop
1000 loops, best of 3: 942 µs per loop
Korzystanie @user2685079's solution
użyciu np.sign
zastąpić pierwszą część, a następnie bez numexpr
oceny -
In [143]: %timeit np.sign(x) * np.log(1+abs(x))
100 loops, best of 3: 3.26 ms per loop
In [144]: %timeit np.sign(x) * ne.evaluate('log(1+abs(x))')
1000 loops, best of 3: 1.66 ms per loop
Czy którekolwiek z zamieszczonych rozwiązań działają dla Ciebie? – Divakar
@Divakar przepraszam, nie mam możliwości sprawdzenia, czy jeszcze. Spróbuję w najbliższym czasie i oznaczyć odpowiedź: – ichernob