Средневзвешенное значение по Пандам для данных панели (T * N) - PullRequest
0 голосов
/ 06 марта 2019

Я хотел рассчитать среднегодовое средневзвешенное значение для некоторых ежедневных наблюдений.Соответственно, мне нужно сначала рассчитать средневзвешенное значение для каждого дня, а затем найти регулярное (одинаково взвешенное) среднее значение для всех дней в году (рисунок данных и желаемый результат приведены ниже.)

Вот мой не-фрагмент рабочего кода:

def ave_annual(s):
    return s.groupby(s.index.year).mean()


wav = lambda x: np.average(x['premium'], weights=x.tna)

df.groupby('date').apply(wav).pipe(ave_annual)

первое агрегирование (на уровне даты (дня)) возвращает все NaN.

Мне удалось вычислить среднее значение пошагово имедленный подход:

master_2 = (master_1.assign(tna_sum =  master_1.groupby('date')
.tna.transform('sum'))[lambda x: x['tna_sum'] > 0 ]

res_premium = master_2.groupby(
'date')['prem_wieghted2'].sum().pipe(ave_annual)

Мне было интересно (1), что плохого в том, что я получаю NaN с, и (2) как я могу использовать этот подход (np.average) для вычисления средних значений длядве переменные.

Данные:

date	ticker	premium	spread	tna
3/4/2013	x	-0.69	0.1261	7.2329
3/4/2013	y	0.096	0.296	49.496
3/4/2013	x	0.142	0.4352	167.5251
3/6/2013	x	-0.69	0.1261	7.2329
3/6/2013	z	0.096	0.296	49.496
3/6/2013	y	0.084	0.21	110
3/4/2019	x	NaN	0.1392	16.431
3/4/2019	y	NaN	NaN	100.6774

enter image description here

Ответы [ 2 ]

1 голос
/ 07 марта 2019

Я думаю, вам нужна операция groupby(...).transform(...).

Твоему примеру трудно следовать. Вот более простой пример: в этом случае я вычисляю годовые веса по столбцу weight_source и применяю его к столбцу data .

df = pd.DataFrame({'data': np.random.rand(1000), 
                   'weight_source': np.random.rand(1000)},
                  index=pd.date_range(start=dt.datetime(2010, 1, 1), periods=1000, freq='D'))

year_sum = df['weight_source'].groupby(df.index.year).transform('sum')

weights = df['weight_source'] / year_sum

weights * df['data']
0 голосов
/ 27 марта 2019

После предположения и примера данных, сделанных экортазаром, приведенный ниже фрагмент является обходным решением.

df = pd.DataFrame({'data': np.random.rand(1000), 
                   'weight_source': np.random.rand(1000)},
                  index=pd.date_range(start="2010/01/01", periods=1000, freq='D'))
def ave_annual(s):
    return s.groupby(s.index.year).mean()


(df.groupby(df.index).apply(lambda x: (x['data'] * x['weight_source']
.div(x['weight_source'].sum())).sum())
.pipe(ave_annual))

Результаты:

    2010    0.535598
    2011    0.493956
    2012    0.517653
...