2015-06-18 12 views
3

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

enter image description here

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

enter image description here

GroupBy проста,

grouped = DF.groupby('id') 

и найти самую раннюю дату, является простым,

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

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

Существует аналогичный вопрос here.

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

Мой dataframe является:

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: Оба ниже ответы являются удивительными. Хотел бы я принять их обоих.

ответ

2

Вы можете использовать применять так:

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 
+0

панды настолько удивительно. Это наследие APL FTW! –

+0

@DTing Я не знал, что 'DF.date' и' DF ["date"] 'были синонимами. Индексирование в Pandas - дикая поездка, что с '[], .ix, .loc. .iloc' и т. д. Я думаю, я добавлю '.' в список. Также - почему эта функция возвращает 'x days'? Как мы можем избавиться от него текстом 'days'? Кажется вполне самонадеянным из Панд, чтобы там вводить текст. На самом деле, столь же насущный вопрос был бы, как операция вернула значение в днях для начала? Почему не было, скажем, лет или месяцев? Очень таинственный материал, происходящий здесь ... –

+0

'days_since_earliest' имеет dtype' timedelta64 [ns] '. Вы можете конвертировать, используя: http://pandas.pydata.org/pandas-docs/dev/timedeltas.html#frequency-conversion. – DTing

2

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 аксессор:

>>> 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 

 Смежные вопросы

  • Нет связанных вопросов^_^