如何在Pandas中生成连续同组递增的rank序列?
解决按连续相同QQ分组生成Order列的问题
首先,先明确你的需求:从order列能看出来,你要的是按seq升序排列后,对连续出现的相同qq进行组内从1开始的编号,而非对每个qq的所有seq记录做全局排名——这也是你当前代码得到result列(不符合预期)的原因。
先把你的数据整理成清晰的表格:
| seq | order | result | |
|---|---|---|---|
| 2881017171 | 6730 | 1 | 1 |
| 2881017170 | 6731 | 1 | 1 |
| 644128000 | 6732 | 1 | 1 |
| 644128000 | 6733 | 2 | 2 |
| 2881017198 | 6734 | 1 | 1 |
| 644128000 | 6735 | 1 | 3 |
| 2881017198 | 6736 | 1 | 2 |
| 2881017192 | 6737 | 1 | 1 |
| 644128000 | 6738 | 1 | 4 |
| 2881017192 | 6739 | 1 | 2 |
| 2881017198 | 6740 | 1 | 3 |
| 285207386 | 6741 | 1 | 1 |
| 2881017198 | 6742 | 1 | 4 |
| 285207386 | 6743 | 1 | 2 |
| 2881017198 | 6744 | 1 | 5 |
| 2881017188 | 6745 | 1 | 1 |
| 2881017170 | 6746 | 1 | 2 |
| 2881017170 | 6747 | 2 | 3 |
| 2881017170 | 6748 | 3 | 4 |
| 644128000 | 6750 | 1 | 5 |
| 2881017198 | 6751 | 1 | 6 |
| 2881017192 | 6752 | 1 | 3 |
| 2881017192 | 6753 | 2 | 4 |
问题原因
你当前的代码a.assign(rs=a.sort_values(['seq'], ascending=True).groupby(['qq'])['seq'].rank(method='first'))是对每个qq的所有seq记录做全局排名,所以会出现644128000第三次出现时rank为3,而不是回到1的情况——这和你要的连续分组编号逻辑完全不同。
解决方法
我们需要先按seq排序,然后识别连续相同的qq组,再在每个组内生成从1开始的编号。具体代码如下:
import pandas as pd # 假设你的数据存储在DataFrame a中 a_sorted = a.sort_values('seq', ascending=True).reset_index(drop=True) # 创建连续分组标识:当当前行qq与上一行不同时,标记为新组 a_sorted['group_id'] = (a_sorted['qq'] != a_sorted['qq'].shift(1)).cumsum() # 生成目标order列:每个连续组内从1开始计数 a_sorted['order'] = a_sorted.groupby('group_id').cumcount() + 1 # 查看结果 print(a_sorted[['qq', 'seq', 'order', 'result']])
代码解释
a_sorted['qq'] != a_sorted['qq'].shift(1):判断当前行的qq是否和上一行不同,返回布尔值序列.cumsum():把布尔值转换为整数(True为1,False为0),累加后得到连续相同qq的唯一分组IDgroupby('group_id').cumcount() + 1:在每个分组内从0开始计数,加1后得到从1开始的编号,完美匹配你需要的order列
运行这段代码后,就能得到你期望的排序结果啦。
内容的提问来源于stack exchange,提问作者peteryoung
相关产品推荐
相关产品推荐

