我推荐这个post。但是我的目标是不同的。
示例
ID TIME
01 2018-07-11
01 2018-07-12
01 2018-07-13
01 2018-07-15
01 2018-07-16
01 2018-07-17
02 2019-09-11
02 2019-09-12
02 2019-09-15
02 2019-09-16
注意:对于每个ID,日期都是唯一的。
期望
ID TIME RANK
01 2018-07-11 1
01 2018-07-12 2
01 2018-07-13 3
01 2018-07-15 1
01 2018-07-16 2
01 2018-07-17 3
02 2019-09-11 1
02 2019-09-12 2
02 2019-09-15 1
02 2019-09-16 2
对于每个ID,连续日期的排名不会更改。如果没有更改,则排名会重新启动。
目标
如何获得结果。
尝试
df.groupby('ID')['TIME'].rank(ascending=True)
失败
答案 0 :(得分:2)
首先,我们检查日期之间的差异,即> 1 day
。然后,我们根据这些差异中的ID
和cumsum
进行分组,并cumulative count
每组`
# df['TIME'] = pd.to_datetime(df['TIME'])
s = df['TIME'].diff().fillna(pd.Timedelta(days=1)).ne(pd.Timedelta(days=1))
df['RANK'] = s.groupby([df['ID'], s.cumsum()]).cumcount().add(1)
ID TIME RANK
0 1 2018-07-11 1
1 1 2018-07-12 2
2 1 2018-07-13 3
3 1 2018-07-15 1
4 1 2018-07-16 2
5 1 2018-07-17 3
6 2 2019-09-11 1
7 2 2019-09-12 2
8 2 2019-09-15 1
9 2 2019-09-16 2
答案 1 :(得分:1)
使用DataFrameGroupBy.diff
来计算TIME
列中每组的差异,比较不等于1
的天数,并通过累积总和创建组,最后传递到GroupBy.cumcount
:
df['TIME'] = pd.to_datetime(df['TIME'])
new = df.groupby('ID', group_keys=False)['TIME'].diff().dt.days.ne(1).cumsum()
df['rank'] = df.groupby(['ID',new]).cumcount().add(1)
print (df)
ID TIME rank
0 1 2018-07-11 1
1 1 2018-07-12 2
2 1 2018-07-13 3
3 1 2018-07-15 1
4 1 2018-07-16 2
5 1 2018-07-17 3
6 2 2019-09-11 1
7 2 2019-09-12 2
8 2 2019-09-15 1
9 2 2019-09-16 2