Панды переиндексируют даты в Groupby

У меня есть фреймворк со спорадическими датами в качестве индекса и столбцами = 'id' и 'num'. Я хотел бы pd.groupby столбец «id» и применить переиндекс к каждой группе во фрейме данных.

Мой образец набора данных выглядит так:

            id  num
2015-08-01  1   3
2015-08-05  1   5
2015-08-06  1   4
2015-07-31  2   1
2015-08-03  2   2
2015-08-06  2   3

Мой ожидаемый результат после pd.reindex с ffill:

            id  num
2015-08-01  1   3
2015-08-02  1   3
2015-08-03  1   3
2015-08-04  1   3
2015-08-05  1   5
2015-08-06  1   4
2015-07-31  2   1
2015-08-01  2   1
2015-08-02  2   1
2015-08-03  2   2
2015-08-04  2   2
2015-08-05  2   2
2015-08-06  2   3

Я пробовал это, среди прочего, безрезультатно: newdf=df.groupby('id').reindex(method='ffill') Что возвращает ошибку: AttributeError: Cannot access callable attribute 'reindex' of 'DataFrameGroupBy' objects, try using the 'apply' method

Любая помощь приветствуется


person clg4    schedule 28.08.2015    source источник


Ответы (1)


Вероятно, есть более изящный способ сделать это, но он работает:

def reindex_by_date(df):
    dates = pd.date_range(df.index.min(), df.index.max())
    return df.reindex(dates).ffill()

df.groupby('id').apply(reindex_by_date).reset_index(0, drop=True)
person JoeCondron    schedule 28.08.2015
comment
Это работает. Хорошая работа. Это займет некоторое время, но я не могу представить, что есть более быстрый и питонический способ сделать это. Благодаря тонну. - person clg4; 28.08.2015
comment
Немного другой вариант - написать возвращаемую часть функции как return df.resample('D').fillna(method='ffill') . Это дает дополнительное преимущество, заключающееся в изменении буквы «D» в части повторной выборки на «B», если вам, например, нужны только рабочие дни (конечно, это зависит от того, что вы хотите). - person Pilik; 28.08.2015
comment
Вы уверены, что это работает Pilik, потому что я сначала пробовал resample, но за пропущенные дни ничего не получилось? В pd.date_range также можно указать разные периоды, например рабочие дни, например pd.date_range(.., offset='B') на рабочие дни. - person JoeCondron; 29.08.2015
comment
@JoeCondron, ты прав, я не знал, что у pd.date_range есть опция смещения. Я скопировал пример, используя pd.read_clipboard(), и мое решение с resample также дает желаемый результат. - person Pilik; 01.09.2015
comment
У меня это решение не работает: все строки становятся NaN. Если я изменю функцию для использования df.reindex(dates, method = 'ffill'), это даст мне TypeError: Cannot compare type 'Timestamp' with type 'str' - person Giacomo; 04.10.2017
comment
@giac_man Похоже, в вашем индексе есть строки, похожие на дату. DatetimIndex будет выглядеть идентично индексу, содержащему строки вида 'YYYY-MM-DD'. Вы можете конвертировать, используя pd.to_datetime - person JoeCondron; 04.10.2017