Свертывание группы данных с течением времени с помощью Pandas - PullRequest
0 голосов
/ 05 октября 2019

Здравствуйте, я пытаюсь объединить / свернуть два кадра данных. Я хотел бы объединить «dfDates» и «dfProducts», а затем развернуть продукты в группе / участниках «dfProducts» до даты, когда появится новая группа / участники. Я пытался использовать внешнее объединение между обоими кадрами данных, но я не знаю, как катить группы ...

Следуйте ниже, как выглядят кадры данных и как я хотел бы 'dfFinal'

dfProducts

   Date      Product

2018-01-01      A  
2018-01-01      B 
2018-01-01      C 
2018-01-03      D
2018-01-03      E
2018-01-03      F

dfDates

   Date        

2018-01-01       
2018-01-02   
2018-01-03       
2018-01-04      

dfFinal

   Date      Product

2018-01-01      A  
2018-01-01      B 
2018-01-01      C 
2018-01-02      A  
2018-01-02      B 
2018-01-02      C 
2018-01-03      D
2018-01-03      E
2018-01-03      F
2018-01-04      D
2018-01-04      E
2018-01-04      F

Ответы [ 2 ]

2 голосов
/ 05 октября 2019

Самый простой вариант, который я вижу, это сначала сгруппировать все по дате, затем переиндексировать до желаемого диапазона, чтобы сбросить nan s в пустые места, а затем заполнить их:

(
    df
    .groupby("Date")
    ['Product']
    .apply(list)
    .reindex(pd.date_range(start=dfDates['Date'].min(), end=dfDates['Date'].max(), freq='D'))
    .fillna(method='ffill')
    .explode()
)

2018-01-01    A
2018-01-01    B
2018-01-01    C
2018-01-02    A
2018-01-02    B
2018-01-02    C
2018-01-03    D
2018-01-03    E
2018-01-03    F
2018-01-04    D
2018-01-04    E
2018-01-04    F
Name: Product, dtype: object
0 голосов
/ 05 октября 2019

Определите следующую функцию:

def getLastDateRows(dat, df):
    rows = df.query('Date == @dat')
    n = rows.index.size
    if n == 0:
        lastDat = df.Date[df.Date < dat].iloc[-1]
        rows = df.query('Date == @lastDat')
    return pd.DataFrame({ 'Date': dat, 'Product': rows.Product })

Затем примените его к каждому dfDates.Date и concat результаты:

pd.concat(dfDates.Date.apply(getLastDateRows, df=dfProducts)\
    .tolist(), ignore_index=True)

Результат такой же, как и ожидалось.

Приложение

Решение, предложенное Рэнди , может быть немного улучшено:

dfProducts.groupby('Date').Product.apply(list)\
    .reindex(dfDates.Date).ffill().explode().reset_index()

Различия:

  • Переиндексирование включено dfDates.Date (не весь диапазон), поэтому результат будет содержать только даты, присутствующие в dfDates , который может содержать преднамеренные "пробелы", например, для выходных.
  • Последний вызов reset_index приводит к тому, что в результате получается DataFrame (неa Series ).
...