前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Pandas高端操作:10行代码解决用户游览日志合并排序问题

Pandas高端操作:10行代码解决用户游览日志合并排序问题

作者头像
朱小五
发布2021-01-20 10:08:28
2600
发布2021-01-20 10:08:28
举报
文章被收录于专栏:凹凸玩数据
作者:小小明,「凹凸数据」专栏作者,Pandas数据处理专家,致力于帮助无数数据从业者解决数据处理难题。

先说问题

下面有一份用户游览日志的数据(复制下面显示的表格后,运行下面的代码才会出现相同的结果,详见《在剪贴板上读取/写入数据,太方便了吧!》):

代码语言:javascript
复制
import pandas as pd
df = pd.read_clipboard() #读取剪切板中的数据
df

结果:

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。

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

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

代码语言:javascript
复制
tmp = df.groupby("uid").get_group('B')
tmp

结果:

uid

start

end

4

B

2

3

5

B

4

7

6

B

10

11

7

B

6

8

8

B

12

15

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

排序后:

代码语言:javascript
复制
tmp = tmp.sort_values('start')
tmp

结果:

uid

start

end

4

B

2

3

5

B

4

7

7

B

6

8

6

B

10

11

8

B

12

15

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

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

代码语言:javascript
复制
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

结果:

uid

start

end

0

B

2

3

1

B

4

8

2

B

10

11

3

B

12

15

完整代码

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

代码语言:javascript
复制
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

结果:

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

好了,完结,撒花!

记得一键三连哦~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 凹凸数据 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 先说问题
  • 对一个用户进行时间合并+排序
  • 完整代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档