split,groupby,在Pandas中结合以找出日期的差异

时间:2015-06-18 02:23:17

标签: python date pandas

我有一个简单的数据框,如下所示:

enter image description here

我想使用groupby按ID进行分组,然后找到一些方法来区分日期,然后将列绑定回数据框,所以我最终得到了这个:

enter image description here

groupby很简单,

grouped = DF.groupby('id')

并且找到最早的日期很简单,

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

但我不确定如何继续。如何应用日期减法操作,然后合并?

有一个类似的问题here

感谢您阅读此内容。

我的数据框是:

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]

修改 以下两个答案都很棒。我希望我能接受他们两个。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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