split, groupby, объединить в Pandas, чтобы найти разницу в датах

У меня есть простой фреймворк, который выглядит так:

введите описание изображения здесь

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

введите описание изображения здесь

Группировка проста,

 grouped = DF.groupby('id') 

и поиск самой ранней даты прост,

 maxdates = grouped['date'].min() 

Но я не уверен, как действовать дальше. Как применить операцию вычитания даты, а затем объединить?

Здесь есть аналогичный вопрос.

Спасибо, что прочитали это далеко.

Мой информационный кадр:

 dates=pd.to_datetime(['2015-01-01', '2015-02-01', '2015-03-01', '2015-04-01', '2015-05-01', '2015-01-01', '2015-01-02', '2015-01-03', '2015-01-04', '2015-01-05']) DF = DataFrame({'id':[1,1,1,1,1,2,2,2,2,2], 'date':dates}) cols = ['id', 'date'] DF=DF[cols] 

EDIT: Оба ответа ниже являются удивительными. Хотел бы я принять их обоих.

Вы можете использовать следующее:

 earliest_by_id = DF.groupby('id')['date'].min() def since_earliest(row): return row.date - earliest_by_id[row.id] DF['days_since_earliest'] = DF.apply(since_earliest, axis=1) print(DF) 

  id date days_since_earliest 0 1 2015-01-01 0 days 1 1 2015-02-01 31 days 2 1 2015-03-01 59 days 3 1 2015-04-01 90 days 4 1 2015-05-01 120 days 5 2 2015-01-01 0 days 6 2 2015-01-02 1 days 7 2 2015-01-03 2 days 8 2 2015-01-04 3 days 9 2 2015-01-05 4 days 

редактировать:

 DF['days_since_earliest'] = DF.apply(since_earliest, axis=1).astype('timedelta64[D]') print(DF) id date days_since_earliest 0 1 2015-01-01 0 1 1 2015-02-01 31 2 1 2015-03-01 59 3 1 2015-04-01 90 4 1 2015-05-01 120 5 2 2015-01-01 0 6 2 2015-01-02 1 7 2 2015-01-03 2 8 2 2015-01-04 3 9 2 2015-01-05 4 

FWIW, используя transform часто может быть проще (и обычно быстрее), чем apply . transform принимает результаты операции groupby и передает его в исходный индекс:

 >>> df["dse"] = df["date"] - df.groupby("id")["date"].transform(min) >>> df id date dse 0 1 2015-01-01 0 days 1 1 2015-02-01 31 days 2 1 2015-03-01 59 days 3 1 2015-04-01 90 days 4 1 2015-05-01 120 days 5 2 2015-01-01 0 days 6 2 2015-01-02 1 days 7 2 2015-01-03 2 days 8 2 2015-01-04 3 days 9 2 2015-01-05 4 days 

Если вы предпочитаете целочисленные дни вместо объектов timedelta, вы можете использовать dt.days accessor:

 >>> df["dse"] = df["dse"].dt.days >>> df id date dse 0 1 2015-01-01 0 1 1 2015-02-01 31 2 1 2015-03-01 59 3 1 2015-04-01 90 4 1 2015-05-01 120 5 2 2015-01-01 0 6 2 2015-01-02 1 7 2 2015-01-03 2 8 2 2015-01-04 3 9 2 2015-01-05 4