如何用Pandas为DataFrame生成基于状态重复的Rank列
实现State的非连续出现Rank列
假设你的DataFrame已经按Date字段排好序,我们可以通过以下步骤快速添加符合要求的Rank列:
1. 构造示例数据(匹配需求场景)
import pandas as pd data = { 'Date': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05', '2023-01-06', '2023-01-07'], 'State': ['State1', 'State1', 'State2', 'State2', 'State1', 'State1', 'State1'], 'Amount': [100, 200, 150, 300, 250, 400, 500] } df = pd.DataFrame(data) df['Date'] = pd.to_datetime(df['Date'])
2. 核心实现代码
# 标记每个连续的State分组:State切换时生成新的分组ID df['block_id'] = (df['State'] != df['State'].shift()).cumsum() # 对每个State,按分组出现的先后顺序分配Rank值 df['Rank'] = df.groupby('State')['block_id'].rank(method='dense').astype(int) # 可选:删除中间临时用的block_id列 df = df.drop('block_id', axis=1)
3. 最终结果示例
运行后将得到完全符合需求的DataFrame:
| Date | State | Amount | Rank |
|---|---|---|---|
| 2023-01-01 | State1 | 100 | 1 |
| 2023-01-02 | State1 | 200 | 1 |
| 2023-01-03 | State2 | 150 | 1 |
| 2023-01-04 | State2 | 300 | 1 |
| 2023-01-05 | State1 | 250 | 2 |
| 2023-01-06 | State1 | 400 | 2 |
| 2023-01-07 | State1 | 500 | 2 |
关键逻辑说明
- 生成block_id:通过
df['State'] != df['State'].shift()判断当前行与上一行的State是否不同,不同则标记为1,相同为0,再用cumsum()累加得到全局唯一的连续分组ID,每个连续出现的State会共享同一个ID。 - 分配Rank:按State分组后,对组内的block_id做密集排名(
method='dense'),确保每个State的首次连续出现Rank为1,后续再次出现的连续块Rank依次递增,完全匹配你的规则。
内容的提问来源于stack exchange,提问作者srgam
相关产品推荐
相关产品推荐

