Как настроить структуру данных, чтобы заставить pandas и numpy сотрудничать?

#python #python-3.x #pandas #numpy

#питон #python-3.x #панды #тупой

Вопрос:

Возникли проблемы с компиляцией кода, основанного на pandas и numpy. Я попытаюсь объяснить проблемы, предоставив уменьшенные рабочие примеры того, в чем заключается проблема.

То, что я в основном пытаюсь сделать, это оптимизация портфеля Markowitz следующим образом.

Сначала у меня есть панды.Фрейм данных, в котором указаны цены закрытия для данного тикера, выглядит следующим образом.

 df = pd.DataFrame()
df['AAPL'] = [1.2,1.4,1.5]
df['GOOGL'] = [2.1,2.4,2.6]
df['DATE'] = ['2017-01-01', '2017-01-02','2017-01-03']
df = df.set_index('DATE')
 

Далее я хочу создать некоторую базовую статистику для передачи в некоторые функции, что я делаю следующим образом:

 returns = df.pct_change()
mean_returns = returns.mean()
cov_matrix = returns.cov()
num_portfolios = 10
risk_free_rate = 0.0178
 

Тип этих статистических данных:

 pandas.core.series.Series
pandas.core.frame.DataFrame
 

Проблемы начинают возникать в следующих функциях:

 def portfolio_annualised_performance(weights, mean_returns, cov_matrix):
    returns = np.sum(mean_returns*weights ) *252
    std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))) * np.sqrt(252)
    return std, returns

def random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate):
    results = np.zeros((3,num_portfolios))
    print('results:',type(results))
    weights_record = []
    for i in range(num_portfolios):
        weights = np.random.random(12)
        weights /= np.sum(weights)
        weights_record.append(weights)
        portfolio_std_dev, portfolio_return = portfolio_annualised_performance(weights, mean_returns, cov_matrix)
        results[0,i] = portfolio_std_dev
        results[1,i] = portfolio_return
        results[2,i] = (portfolio_return - risk_free_rate) / portfolio_std_dev
    #print('results[2,0]:',type(results[2,0]))
    #print('std', type(portfolio_std_dev))
    #print(portfolio_return)
    return results, weights_record


def display_simulated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate):
    results, weights = random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate)


    max_sharpe_idx = np.argmax(np.array(results[2]))
    sdp, rp = results[0,max_sharpe_idx], results[1,max_sharpe_idx]
    max_sharpe_allocation = pd.DataFrame(weights[max_sharpe_idx],index=df.columns,columns=['allocation'])
    max_sharpe_allocation.allocation = [round(i*100,2)for i in max_sharpe_allocation.allocation]
    max_sharpe_allocation = max_sharpe_allocation.T

    min_vol_idx = np.argmin(results[0])
    sdp_min, rp_min = results[0,min_vol_idx], results[1,min_vol_idx]
    min_vol_allocation = pd.DataFrame(weights[min_vol_idx],index=df.columns,columns=['allocation'])
    min_vol_allocation.allocation = [round(i*100,2)for i in min_vol_allocation.allocation]
    min_vol_allocation = min_vol_allocation.T
 

При попытке запустить:

отображение_simulated_ef_with_random(cov_matrix, mean_returns, num_portfolios, risk_free_rate)

Появляется следующая ошибка

 ----> 2     results, weights = random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate)

---> 15         results[0,i] = portfolio_std_dev

ValueError: setting an array element with a sequence.
 

Что я делаю не так и как я могу это исправить?

Комментарии:

1. Какую версию python, pandas, numpy вы используете? Для меня это работает без ошибок (после изменения размера весов на weights = np.random.random(2) , поскольку вы предоставляете только 2 ресурса)

2. Я использую numpy 1.14.3 и pandas 0.23.0. О, извините за это, у меня есть 12 ресурсов в моем полном примере, опубликовал ссылку на полный код, если интересно.

3. @KenSyme Я вижу, что это сработало и для меня, проблема возникает на поздней стадии, которую я понял, опубликую.

4. Вместо того чтобы говорить нам, «где начинаются проблемы», дайте нам конкретную строку кода, которая не работает, и каким, по вашему мнению, должен быть результат.

5. Я опубликовал всю ошибку целиком, так как считаю, что она глубоко укоренилась в структуре данных, и считаю, что ее нельзя исправить, изменив только одну строку кода. Но я могу быть совершенно неправ, как это часто бывает.

Ответ №1:

Вы вызываете свою функцию с параметрами в неправильном порядке. Поменяйте местами первые два, и все работает нормально:

 display_simulated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate)
 

Комментарии:

1. Мне даже не приходило в голову об этом, стыдно, но вы только что решили проблему, которая у меня была в течение 2 дней. Спасибо, что уделили мне внимание деталям и время!