2016-05-25 4 views
4

У меня есть ежедневная доходность с трех рынков (GLD, SPY и USO). Моя цель - рассчитать среднюю попарную корреляцию от корреляционной матрицы на основе проката 130 дней.Средняя средняя попарная корреляция в Python

Моя точка была:

import numpy as np 
import pandas as pd 
import os as os 
import pandas.io.data as web 
import datetime as datetime 
from pandas.io.data import DataReader 

stocks = ['spy', 'gld', 'uso'] 
start = datetime.datetime(2010,1,1) 
end = datetime.datetime(2016,1,1) 

df = web.DataReader(stocks, 'yahoo', start, end) 
adj_close_df = df['Adj Close'] 

returns = adj_close_df.pct_change(1).dropna() 
returns = returns.dropna() 

rollingcor = returns.rolling(130).corr() 

Это создает панель корреляционных матриц. Однако извлечение нижних (или верхних) треугольников, удаление диагоналей, а затем вычисление среднего для каждого наблюдения - это то, где я нарисовал пробел. В идеале я хотел бы, чтобы результат для каждой даты был в серии, где я могу проиндексировать ее по датам.

Возможно, я начал с неправильного места, но любая помощь будет оценена по достоинству.

+0

По средней корреляции вы имеете в виду в среднем 3 значения в этом случае для каждой даты? (все попарные комбинации) – aldanor

+0

Да среднее значение из трех значений. – Joe

ответ

3

Чтобы получить среднюю парную корреляцию, вы можете найти сумму корреляционной матрицы, вычесть n (единицы по диагонали), делить на 2 (симметрию) и, наконец, делить на n (в среднем). Я думаю, что это нужно сделать, это:

>>> n = len(stocks) 
>>> ((rollingcor.sum(skipna=0).sum(skipna=0) - n)/2)/n 
Date 
2010-01-05   NaN 
2010-01-06   NaN 
2010-01-07   NaN 
       ... 
2015-12-29 0.164356 
2015-12-30 0.168102 
2015-12-31 0.166462 
dtype: float64 
+0

Отлично! Работал как шарм. Спасибо! – Joe

1

Вы можете использовать numpy «s tril для доступа нижнего треугольника dataframe.

def tril_sum(df): 
    # -1 ensures we skip the diagonal 
    return np.tril(df.unstack().values, -1).sum() 

Рассчитывает сумму нижнего треугольника матрицы. Обратите внимание на unstack() в середине этого. Я ожидаю, что у меня будет несколько целых строк, которые мне нужно будет привязать к кадру данных.

Затем нанесите его на панель

n = len(stock) 
avg_cor = rollingcor.dropna().to_frame().apply(tril_sum)/((n ** 2 - n)/2) 

Похож:

print avg_cor.head() 

Date 
2010-07-12 0.398973 
2010-07-13 0.403664 
2010-07-14 0.402483 
2010-07-15 0.403252 
2010-07-16 0.407769 
dtype: float64 

Этот ответ пропускает диагонали.

+0

Спасибо! Также работает для меня. Большое спасибо. – Joe