Pandas基础|用户游览日志时间合并排序

举报
小小明-代码实体 发表于 2021/10/11 22:33:53 2021/10/11
【摘要】 作者:小小明,Pandas数据处理专家,致力于帮助无数数据从业者解决数据处理难题。 需求说明 有一份下面格式用户游览日志的数据(复制下面显示的表格后,运行下面的代码才会出现相同的结果): ...

作者:小小明,Pandas数据处理专家,致力于帮助无数数据从业者解决数据处理难题。

需求说明

有一份下面格式用户游览日志的数据(复制下面显示的表格后,运行下面的代码才会出现相同的结果):

import pandas as pd

df = pd.read_clipboard()
df

  
 
  • 1
  • 2
  • 3
  • 4

结果:

uid start end
0 A 1 2
1 A 4 7
2 A 3 6
3 A 8 9
4 B 2 3
5 B 4 7
6 B 10 11
7 B 6 8
8 B 12 15
9 C 14 15

其中uid表示每个用户,start表示起始游览时间,end表示结束游览的时间,从上表可以看到,存在游览时间重叠的情况,例如用户A的游览时间3-6和4-7重叠,可以认为游览时间是3-7。

我们现在要做的事就是把每个用户的存在重叠的游览时间合并到一起,最终并按照时间顺序排序显示。

注意:3-4和4-6也属于重叠的时间,可以合并为3-6。

先对一个用户进行时间合并并排序

取出一个用户的数据,用于测试操作:

tmp = df.groupby("uid").get_group('B')
tmp

  
 
  • 1
  • 2

结果:

uid start end
4 B 2 3
5 B 4 7
6 B 10 11
7 B 6 8
8 B 12 15

观察发现,要解决这个问题,我们首先需要对数据按照开始时间排序。

img

排序后:

tmp = tmp.sort_values('start')
tmp

  
 
  • 1
  • 2

结果:

uid start end
4 B 2 3
5 B 4 7
7 B 6 8
6 B 10 11
8 B 12 15

观察排序后的数据,我们就能很快的观察出合并的规则:

当前游览记录的的起始时间小于等于上一条记录的结束时间时就进行合并,非常简单:

result = []
for uid, start, end in tmp.values:
    # 如果结果集中还没有数据或者当前记录的起始时间大于上一条记录的结束时间
    # 就可以直接将当前记录加入到结果集
    if not result or start > result[-1][2]:
        result.append([uid, start, end])
    else:
        # 否则,说明可以将当前记录与上一条记录合并
        # 合并方法是如果当前记录的结束时间大于上一条记录的结束时间,
        # 则上一条记录的结束时间修改为当前记录的结束时间
        result[-1][2] = max(result[-1][2], end)
tmp = pd.DataFrame(result, columns=["uid", "start", "end"])
tmp

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

结果:

uid start end
0 B 2 3
1 B 4 8
2 B 10 11
3 B 12 15

完整代码

然后我们整理一下完整的处理代码:

result = []
for uid, tmp in df.groupby("uid"):
    tmp = tmp[["start", "end"]].sort_values('start')
    rows = []
    for start, end in tmp.values:
        if not rows or start > rows[-1][2]:
            rows.append([uid, start, end])
        else:
            rows[-1][2] = max(rows[-1][2], end)
    tmp = pd.DataFrame(rows, columns=["uid", "start", "end"])
    result.append(tmp)
result = pd.concat(result)
result

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

结果:

uid start end
0 A 1 2
1 A 3 7
2 A 8 9
0 B 2 3
1 B 4 8
2 B 10 11
3 B 12 15
0 C 14 15

好了,完结,撒花!

文章来源: xxmdmst.blog.csdn.net,作者:小小明-代码实体,版权归原作者所有,如需转载,请联系作者。

原文链接:xxmdmst.blog.csdn.net/article/details/112387087

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。