间隙和孤岛Python数据帧熊猫



我有以下问题,正如我所读到的,它被称为"缺口和岛屿"问题。我的数据样本如下(我也排除了一些与用户相关的列,但我想方法是一样的(:

2021年2月1日//tr>2021年3月1日2021年4月1日2021年5月1日//tr>2021年6月1日//tr>2021年7月1日2021年8月1日2021年9月1日//tr>2021年1月10日//tr>2021年1月11日//tr>2021年1月12日//tr>2021年1月14日//tr>2021年1月15日//tr>2021年1月16日//tr>2021年1月17日//tr>2021年1月18日//tr>2021年1月21日//tr>2021年1月22日//tr>2021年1月23日//tr>2021年1月24日//tr>2021年1月25日//tr>
用户报告日期
john 标记 2021年1月
john 标记
john 标记
john 标记
john 标记
john 标记
john 标记
john 标记
john 标记
john 标记
john 标记
john 尼克
john 尼克 2021年1月13日
john 尼克
john 尼克
john 尼克
john 尼克
john 尼克
john 尼克 2021年1月19日
john 尼克 2021年1月20日
john 标记
john 标记
john 标记
john 标记
john 标记

正如@Arne在评论中提到的,如果您分配一个新的数据帧列,然后用userreports_to对其进行聚合,则链接答案确实有效。

分配

# ADD NEW GROUP SEQ COLUMN
staff_df = (
staff_df.assign(
group_seq = lambda df: (
df["reports_to"].ne(df["reports_to"].shift()).cumsum()
)
)
)
staff_df
#     user reports_to       date  group_seq
# 0   john       mark 2021-01-01          1
# 1   john       mark 2021-01-02          1
# 2   john       mark 2021-01-03          1
# 3   john       mark 2021-01-04          1
# 4   john       mark 2021-01-05          1
# 5   john       mark 2021-01-06          1
# 6   john       mark 2021-01-07          1
# 7   john       mark 2021-01-08          1
# 8   john       mark 2021-01-09          1
# 9   john       mark 2021-01-10          1
# 10  john       mark 2021-01-11          1
# 11  john       nick 2021-01-12          2
# 12  john       nick 2021-01-13          2
# 13  john       nick 2021-01-14          2
# 14  john       nick 2021-01-15          2
# 15  john       nick 2021-01-16          2
# 16  john       nick 2021-01-17          2
# 17  john       nick 2021-01-18          2
# 18  john       nick 2021-01-19          2
# 19  john       nick 2021-01-20          2
# 20  john       mark 2021-01-21          3
# 21  john       mark 2021-01-22          3
# 22  john       mark 2021-01-23          3
# 23  john       mark 2021-01-24          3
# 24  john       mark 2021-01-25          3

聚合

agg_df = (
staff_df.groupby(["user", "reports_to", "group_seq"]).agg(
min = ("date", "min"), max = ("date", "max")
).sort_values(["min", "max"])
)
agg_df
#                                  min        max
# user reports_to group_seq                      
# john mark       1         2021-01-01 2021-01-11
#      nick       2         2021-01-12 2021-01-20
#      mark       3         2021-01-21 2021-01-25

代码在这里。

import pandas as pd
from io import StringIO
df = '''
user    reports_to  date
john    mark    1/1/2021
john    mark    2/1/2021
john    mark    3/1/2021
john    mark    4/1/2021
john    mark    5/1/2021
john    mark    6/1/2021
john    mark    7/1/2021
john    mark    8/1/2021
john    mark    9/1/2021
john    mark    10/1/2021
john    mark    11/1/2021
john    nick    12/1/2021
john    nick    13/1/2021
john    nick    14/1/2021
john    nick    15/1/2021
john    nick    16/1/2021
john    nick    17/1/2021
john    nick    18/1/2021
john    nick    19/1/2021
john    nick    20/1/2021
john    mark    21/1/2021
john    mark    22/1/2021
john    mark    23/1/2021
john    mark    24/1/2021
john    mark    25/1/2021
'''
inf=StringIO(df)
df = pd.read_csv(inf,sep="t")

df['group'] = (( (df.user != df.user.shift() ) | (df.reports_to != df.reports_to.shift())  ).cumsum())
# must do this 
df['date'] = pd.to_datetime(df['date']) 
result = ( df.groupby(['user','group','reports_to'])['date']
.agg({min, max})
.rename(columns={'min': 'from','max':'to'})
.reset_index() )

最新更新