Я запускаю большую программу Python для оптимизации портфельных весов для оптимизации портфеля (Markowitz) в финансах. Когда я просматриваю код, 90% времени выполнения затрачивается на расчет возврата портфеля, что делается миллионы раз. Что я могу сделать, чтобы ускорить мой код? Я попытался:Как ускорить профилированный код NumPy - векторизация, Numba?
- векторизации расчет возвращается: сделал код медленнее, от 1,5 мс до 3 мс
- использовал функцию autojit от Numba ускорить код: отсутствие изменений
См. Пример ниже - любые предложения?
import numpy as np
def get_pf_returns(weights, asset_returns, horizon=60):
'''
Get portfolio returns: Calculates portfolio return for N simulations,
assuming monthly rebalancing.
Input
-----
weights: Portfolio weight for each asset
asset_returns: Monthly returns for each asset, potentially many simulations
horizon: 60 months (hard-coded)
Returns
-------
Avg. annual portfolio return for each simulation at the end of 5 years
'''
pf = np.ones(asset_returns.shape[1])
for t in np.arange(horizon):
pf *= (1 + asset_returns[t, :, :].dot(weights))
return pf ** (12.0/horizon) - 1
def get_pf_returns2(weights, asset_returns):
''' Alternative '''
return np.prod(1 + asset_returns.dot(weights), axis=0) ** (12.0/60) - 1
# Example
N, T, sims = 12, 60, 1000 # Settings
weights = np.random.rand(N)
weights *= 1/np.sum(weights) # Sample weights
asset_returns = np.random.randn(T, sims, N)/100 # Sample returns
# Calculate portfolio risk/return
pf_returns = get_pf_returns(weights, asset_returns)
print np.mean(pf_returns), np.std(pf_returns)
# Timer
%timeit get_pf_returns(weights, asset_returns)
%timeit get_pf_returns2(weights, asset_returns)
EDIT
Решение: Matmul был самым быстрым на моей машине:
def get_pf_returns(weights, asset_returns):
return np.prod(1 + np.matmul(asset_returns, weights), axis=0) ** (12.0/60) - 1
Спасибо! Это большая помощь, чтобы знать, чего я могу ожидать, тогда я рассмотрю остальную часть кода. –