按等级分组连续月份按熊猫分组

时间:2020-06-22 08:10:05

标签: python pandas

这与这篇文章enter link description here有所不同。

示例

ID    TIME
01    2018-07-01
01    2018-08-01
01    2018-09-01
01    2018-11-01
01    2018-12-01
01    2019-01-01
02    2019-01-01
02    2019-02-01
02    2019-03-01
02    2020-01-01

注意:对于每个ID,日期都是唯一的,日期格式为%Y-%m-01TIME的类型是数据时间。

期望

ID    TIME         RANK
01    2018-07-01    1
01    2018-08-01    2
01    2018-09-01    3
01    2018-11-01    1
01    2018-12-01    2
01    2019-01-01    3
02    2019-01-01    1
02    2019-02-01    2
02    2019-03-01    3
02    2020-01-01    2

尝试

s = df['TIME'].diff().fillna(pd.Timedelta(days=30)).ne(pd.Timedelta(days=30))
df['RANK'] = s.groupby([df['ID'], s.cumsum()]).cumcount().add(1)

new = df.groupby('ID', group_keys=False)['TIME'].diff().dt.days.ne(30).cumsum()
df['rank'] = df.groupby(['ID',new]).cumcount().add(1)

但是当连续的TIME2020-02-012020-03-01时失败了。

1 个答案:

答案 0 :(得分:1)

您可以通过Series.dt.to_period将日期时间转换为月份,然后通过DataFrameGroupBy.diff将值的差异MonthEnd与累积总和进行比较,最后使用GroupBy.cumcount

df['TIME'] = pd.to_datetime(df['TIME']).dt.to_period('M')
new = df.groupby('ID', group_keys=False)['TIME'].diff().ne(pd.offsets.MonthEnd()).cumsum()
df['rank'] = df.groupby(['ID',new]).cumcount().add(1)
print (df)
  ID     TIME  RANK  rank
0   1  2018-07     1     1
1   1  2018-08     2     2
2   1  2018-09     3     3
3   1  2018-11     1     1
4   1  2018-12     2     2
5   1  2019-01     3     3
6   2  2019-01     1     1
7   2  2019-02     2     2
8   2  2019-12     1     1
9   2  2020-01     2     2