У меня есть таблица, которая выглядит следующим образом:
portfolio_id date product_rank product_name
0 101010 2008-01-31 1 aa
1 101010 2008-01-31 2 bb
2 202020 2008-02-28 1 aaa
3 202020 2008-02-28 2 bbb
4 101010 2008-04-30 1 aa
5 101010 2008-04-30 2 bb
6 101010 2008-04-30 3 xx
7 202020 2008-06-30 1 aaa
8 202020 2008-06-30 2 ccc
Кадр данных можно воспроизвести, используя следующий код:
columns = ['portfolio_id','date','product_rank','product_name']
sample = pd.DataFrame(columns=columns)
sample = sample.append({'portfolio_id':101010, 'date':'2008-01-31','product_rank':1,'product_name':'aa'},ignore_index=True)
sample = sample.append({'portfolio_id':101010, 'date':'2008-01-31','product_rank':2,'product_name':'bb'},ignore_index=True)
sample = sample.append({'portfolio_id':202020, 'date':'2008-02-28','product_rank':1,'product_name':'aaa'},ignore_index=True)
sample = sample.append({'portfolio_id':202020, 'date':'2008-02-28','product_rank':2,'product_name':'bbb'},ignore_index=True)
sample = sample.append({'portfolio_id':101010, 'date':'2008-04-30','product_rank':1,'product_name':'aa'},ignore_index=True)
sample = sample.append({'portfolio_id':101010, 'date':'2008-04-30','product_rank':2,'product_name':'bb'},ignore_index=True)
sample = sample.append({'portfolio_id':101010, 'date':'2008-04-30','product_rank':3,'product_name':'xx'},ignore_index=True)
sample = sample.append({'portfolio_id':202020, 'date':'2008-06-30','product_rank':1,'product_name':'aaa'},ignore_index=True)
sample = sample.append({'portfolio_id':202020, 'date':'2008-06-30','product_rank':2,'product_name':'ccc'},ignore_index=True)
Я пытаюсь выполнить повторную выборку каждого портфеля в данные с месячной периодичностью, обратное заполнение значений product_rank и product_name. Я также хотел бы обозначить периоды как заполненные.
Другими словами, две задачи:
- Резервное копирование данных за отсутствующие месяцы на уровне портфеля
например, для портфеля 101010, Исходный набор данных включает только точки данных за январь и апрель. Значения за февраль и март должны быть заполнены на значениях за апрель. Заполнение должно быть сделано на уровне портфеля, это означает, что каждый продукт в портфеле должен быть обратно заполнен к предыдущему месяцу. Заполнение должно быть до самого последнего предыдущего месяца.
Подсчитать количество периодов, заполненных назад
Если точки данных существуют в исходном наборе данных, то период back_filled равен 0. Если он был заполнен, то подсчитайте количество периодов, когда точка данных была заполнены для. Например, поскольку данные за июнь существовали, а март не существовал для идентификатора 202020, число периодов с обратным заполнением за март 2008 года для идентификатора 202020 должно составлять 3 периода.
Цель хотела бы, чтобы конечный результат выглядел следующим образом:
portfolio_id date product_rank product_name period_backfilled
101010 2008-01-31 1 aa 0
101010 2008-01-31 2 bb 0
101010 2008-02-28 1 aa 2
101010 2008-02-28 2 bb 2
101010 2008-02-28 3 xx 2
202020 2008-02-28 1 aaa 0
202020 2008-02-28 2 bbb 0
101010 2008-03-31 1 aa 1
101010 2008-03-31 2 bb 1
101010 2008-03-31 3 xx 1
202020 2008-03-31 1 aaa 3
202020 2008-03-31 2 ccc 3
101010 2008-04-30 1 aa 0
101010 2008-04-30 2 bb 0
101010 2008-04-30 3 xx 0
202020 2008-04-30 1 aaa 2
202020 2008-04-30 2 ccc 2
202020 2008-05-31 1 aaa 1
202020 2008-05-31 2 ccc 1
202020 2008-06-30 1 aaa 0
202020 2008-06-30 2 ccc 0
Чтобы экстраполировать данные на месячный уровень, я попытался:
sample.groupby('portfolio_id').apply(lambda x: x.set_index('date').resample('M'))
Это не работает, потому что есть несколько записей для каждого portfolio_id на одну и ту же дату. Группировка и повторная выборка требуют, чтобы идентификатор_порта здесь был уникальным для каждой даты.
Для числа периодов с обратной засыпкой я попытался установить bfill (limit = n), но это дает мне только фиксированное число периодов с обратной засыпкой. Любая идея о том, как я мог бы маркировать количество периодов с обратной засыпкой?
Это большой набор данных, поэтому любое повышение эффективности будет высоко ценится.
Спасибо всем большое за помощь!