Панды Групер не повышают частоту, как ожидалось - PullRequest
1 голос
/ 19 сентября 2019

Рассмотрим серию с MultiIndex, которая обеспечивает естественное значение группировки на уровне 0 и временные ряды на уровне 1:

s = pd.Series(range(12), index=pd.MultiIndex.from_product([['a','b','c'],
              pd.date_range(start='2019-01-01', freq='3D', periods=4)], names=['grp','ts']))
print(s)
grp  ts
a    2019-01-01     0
     2019-01-04     1
     2019-01-07     2
     2019-01-10     3
b    2019-01-01     4
     2019-01-04     5
     2019-01-07     6
     2019-01-10     7
c    2019-01-01     8
     2019-01-04     9
     2019-01-07    10
     2019-01-10    11
Length: 12, dtype: int64

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

s.groupby(['grp', pd.Grouper(level=1, freq='D')]).ffill()

, который дает неожиданные результаты;а именно, это ничего не делает.Результат - ровно s, а не то, что я хотел бы:

grp ts
a   2019-01-01   0
    2019-01-02   0
    2019-01-03   0
    2019-01-04   1
    2019-01-05   1
    2019-01-06   1
    2019-01-07   2
    2019-01-08   2
    2019-01-09   2
    2019-01-10   3
b   2019-01-01   4
    2019-01-02   4
    2019-01-03   4
    2019-01-04   5
    2019-01-05   5
    2019-01-06   5
    2019-01-07   6
    2019-01-08   6
    2019-01-09   6
    2019-01-10   7
c   2019-01-01   8
    2019-01-02   8
    2019-01-03   8
    2019-01-04   9
    2019-01-05   9
    2019-01-06   9
    2019-01-07  10
    2019-01-08  10
    2019-01-09  10
    2019-01-10  11
Length: 30, dtype: int64

Я могу изменить частоту Grouper или функцию повторной выборки на тот же эффект.Единственный обходной путь, который я нашел, был с помощью творческого обмана, чтобы заставить простой индекс временных рядов для каждой группы (спасибо Аллену за предоставленный ответ https://stackoverflow.com/a/44719843/3109201):

s.reset_index(level=1).groupby('grp').apply(lambda s: s.set_index('ts').resample('D').ffill())

, который немного отличается от того, что я первоначально просилпотому что он возвращает DataFrame:

                 0
grp ts
a   2019-01-01   0
    2019-01-02   0
    2019-01-03   0
    2019-01-04   1
    2019-01-05   1
    2019-01-06   1
    2019-01-07   2
    2019-01-08   2
    2019-01-09   2
    2019-01-10   3
b   2019-01-01   4
    2019-01-02   4
    2019-01-03   4
    2019-01-04   5
    2019-01-05   5
    2019-01-06   5
    2019-01-07   6
    2019-01-08   6
    2019-01-09   6
    2019-01-10   7
c   2019-01-01   8
    2019-01-02   8
    2019-01-03   8
    2019-01-04   9
    2019-01-05   9
    2019-01-06   9
    2019-01-07  10
    2019-01-08  10
    2019-01-09  10
    2019-01-10  11

[30 rows x 1 columns]

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

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019

используйте series.asfreq(), что соответствует отсутствующим датам.

def filldates(s_in):
  s_in.reset_index(level="grp",drop=True,inplace=True)
  s_in= s_in.asfreq("1D",method='ffill')
  return s_in
s.groupby(level=0).apply(filldates)
0 голосов
/ 19 сентября 2019

Это не имеет никакого эффекта просто потому, что частота его серий меньше дневной.Почему вы предполагаете, что я должен дать значения NaN?

ALTERNATIVE

Вы можете использовать pandas.Series.repeat , вычисляя количество раз, которое будетповторяется GroupBy.Series.diff :

mult=s.reset_index().groupby('grp')['ts'].diff().dt.days.shift(-1).fillna(1)
s.repeat(mult)

grp  ts        
a    2019-01-01     0
     2019-01-01     0
     2019-01-01     0
     2019-01-04     1
     2019-01-04     1
     2019-01-04     1
     2019-01-07     2
     2019-01-07     2
     2019-01-07     2
     2019-01-10     3
b    2019-01-01     4
     2019-01-01     4
     2019-01-01     4
     2019-01-04     5
     2019-01-04     5
     2019-01-04     5
     2019-01-07     6
     2019-01-07     6
     2019-01-07     6
     2019-01-10     7
c    2019-01-01     8
     2019-01-01     8
     2019-01-01     8
     2019-01-04     9
     2019-01-04     9
     2019-01-04     9
     2019-01-07    10
     2019-01-07    10
     2019-01-07    10
     2019-01-10    11
...