How Do I Speed Up Profiled Numpy Code - Vectorizing, Numba?
Solution 1:
In my environment, mutmul (@) has a modest time advantage over einsum and dot:
In[27]: np.allclose(np.einsum('ijk,k',asset_returns,weights),asset_returns@weig
...: hts)
Out[27]: TrueIn[28]: %timeitasset_returns@weights100loops, bestof3: 3.91msperloopIn[29]: %timeitnp.einsum('ijk,k',asset_returns,weights)
100loops, bestof3: 4.73msperloopIn[30]: %timeitnp.dot(asset_returns,weights)
100loops, bestof3: 6.8msperloopI think times are limited by the total number of calculations, more than the coding details. All of these pass the calculation to compiled numpy code. The fact that your original looped version is relatively fast probably has to do with the small number of loops (only 60), and memory management issues in the fuller dot.
And numba is probably not replacing the dot code.
So a tweak here or there might speed up your code by a factor of 2, but don't expect an order of magnitude improvement.
Solution 2:
Here's a version that uses np.einsum to get a little bit of a speed-up:
defget_pf_returns3(weights, asset_returns, horizon=60):
pf = np.ones(asset_returns.shape[1])
z = np.einsum("ijk,k -> ij",asset_returns[:horizon,:,:], weights)
pf = np.multiply.reduce(1 + z)
return pf ** (12.0 / horizon) - 1And then timings:
%timeit get_pf_returns(weights, asset_returns)
%timeit get_pf_returns3(weights, asset_returns)
print np.allclose(get_pf_returns(weights, asset_returns), get_pf_returns3(weights, asset_returns))
# 1000 loops, best of 3: 727 µs per loop
# 1000 loops, best of 3: 638 µs per loop
# True
The timings on your machine could be different depending on hardware and the libraries numpy is compiled against.
Post a Comment for "How Do I Speed Up Profiled Numpy Code - Vectorizing, Numba?"