У меня есть набор данных, который для каждого наблюдения имеет дату начала и дату окончания.Для данного набора дат я хочу рассчитать средневзвешенное значение наблюдений, у которых начальная дата меньше или равна этой дате, а конечная дата больше или равна этой дате.Я также хочу сделать это для разных групп в наборе данных.
Мне удалось сделать это с помощью цикла, но он довольно медленный, и у меня есть ощущение, что есть лучший способ сделать это.Буду признателен за любую помощь!
Вот мой текущий код с некоторыми тестовыми данными
# Setup
import pandas as pd
import numpy as np
# Dates to loop over and df to hold result
dates = pd.date_range(start='10/1/2011', periods=5, freq='M')
result = pd.DataFrame(columns=["date","calc"])
result['date'] = dates
result = result.set_index('date')
# Test data
data = {"group": ['group1', 'group2']*5,
"start_date": pd.to_datetime(['2011-11-02', '2011-11-03', '2011-11-02', '2011-11-01','2011-11-04', '2011-11-04', '2011-11-04', '2011-11-07',
'2011-11-07', '2011-11-07']),
"end_date": pd.to_datetime(['2012-02-02', '2011-11-17', '2011-11-16', '2011-12-01', '2012-02-06', '2011-11-18', '2012-02-06', '2011-12-07',
'2012-02-07', '2012-03-07']),
"value": np.random.randint(100, size=10)}
df = pd.DataFrame(data)
# For one group
df2 = df[df.group == 'group1']
for date in dates:
tmp = pd.DataFrame()
tmp = df2.loc[(df2.start_date <= date) & (df2.end_date >= date)]
if tmp.empty:
continue
tmp['volume_x_days'] = tmp.apply(lambda x: (x.end_date - date).days * x.value, axis=1)
result.loc[date, "calc"] = tmp.volume_x_days.sum() / tmp.value.sum()
Вывод этого должен быть средневзвешенным значением для каждой даты.Как то так:
calc
date
2011-10-31 NaN
2011-11-30 56.8957
2011-12-31 44.7739
2012-01-31 13.7739
2012-02-29 7