Панды: групповая пересылка с указателем даты и времени

У меня есть набор данных, который имеет две колонки: компания и значение.
Имеет индекс даты и времени, который содержит дубликаты (в один и тот же день разные компании имеют разные значения). В значениях отсутствуют данные, поэтому я хочу переслать заполненные отсутствующие данные предыдущим назначением данных из той же компании.

Тем не менее, я не могу найти хороший способ сделать это, не сталкиваясь со странными групповыми ошибками, предполагая, что я делаю что-то не так.

Данные игрушки:

a = pd.DataFrame({'a': [1, 2, None], 'b': [12,None,14]})
a.index = pd.DatetimeIndex(['2010', '2011', '2012'])  
a = a.unstack() 
a = a.reset_index().set_index('level_1') 
a.columns = ['company', 'value'] 
a.sort_index(inplace=True)

Попытки решения (не работали:ValueError: cannot reindex from a duplicate axis):

a.groupby('company').ffill() 
a.groupby('company')['value'].ffill() 
a.groupby('company').fillna(method='ffill')

Хакерское решение (которое дает желаемый результат, но, очевидно, это просто уродливое решение):

a['value'] = a.reset_index().groupby(
    'company').fillna(method='ffill')['value'].values

Вероятно, есть простой и элегантный способ сделать это, как это выполняется в Pandas?

Ответы на вопрос(3)

Одним из способов является использованиеtransform функция для заполненияvalue столбец за группой по:

import pandas as pd
a['value'] = a.groupby('company')['value'].transform(lambda v: v.ffill())

a
#          company  value
#level_1        
#2010-01-01      a    1.0
#2010-01-01      b   12.0
#2011-01-01      a    2.0
#2011-01-01      b   12.0
#2012-01-01      a    2.0
#2012-01-01      b   14.0

Для сравнения исходный фрейм данных выглядит так:

#            company    value
#level_1        
#2010-01-01        a      1.0
#2010-01-01        b     12.0
#2011-01-01        a      2.0
#2011-01-01        b      NaN
#2012-01-01        a      NaN
#2012-01-01        b     14.0

Можете добавить'company' к индексу, делая его уникальным, и сделать простойffill с помощьюgroupby:

a = a.set_index('company', append=True)
a = a.groupby(level=1).ffill()

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

a = a.reset_index(level=1)

Мне нравится использовать укладку и разборку. В этом случае требуется, чтобы я добавил индекс с'company'.

a.set_index('company', append=True).unstack().ffill() \
                                   .stack().reset_index('company')

тайминг

Заключение Решение @ Psidom лучше всего работает в обоих случаях.

данные игрушки

большая игрушка

np.random.seed([3,1415])
n = 10000
a = pd.DataFrame(np.random.randn(n, 10),
                 pd.date_range('2014-01-01', periods=n, freq='H', name='Time'),
                 pd.Index(list('abcdefghij'), name='company'))

a *= np.random.choice((1, np.nan), (n, 10), p=(.6, .4))

a = a.stack(dropna=False).rename('value').reset_index('company')

Ваш ответ на вопрос