如何基于Pandas DataFrame的另一列生成特定规则的计数器列?
Pandas按分段规则生成计数器列解决方案
首先是你创建的DataFrame代码:
import numpy as np import pandas as pd Range = np.arange(0,9,1) A={ 0:2, 1:2, 2:2, 3:2, 4:3, 5:3, 6:3, 7:2, 8:2 } Table = pd.DataFrame({"Row": Range}) Table["Intervals"]=(Table["Row"]%9).map(A)
生成的DataFrame如下:
| Row | Intervals |
|---|---|
| 0 | 2 |
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
| 4 | 3 |
| 5 | 3 |
| 6 | 3 |
| 7 | 2 |
| 8 | 2 |
你的需求是新增一列Counter,预期值为[1,2,1,2,1,2,3,1,2],计数规则为:
- 当
Intervals为2时,每连续2个为一组,组内计数1、2循环 - 当
Intervals为3时,每连续3个为一组,组内计数1、2、3
解决步骤
问题出在单纯按Intervals分组会把所有相同值的行合并,而不是按连续相同的分段分组。我们需要先标记连续相同的Intervals分段,再在每个分段内生成对应计数器:
- 生成连续分段的标识列
# 标记连续相同的Intervals组,每次值变化时组号+1 Table['group'] = (Table['Intervals'] != Table['Intervals'].shift()).cumsum()
- 对每个分段生成符合规则的计数器
用groupby结合自定义函数,根据每个分段的Intervals值生成循环计数:
def get_counter(group): interval_val = group['Intervals'].iloc[0] # 生成重复的计数序列,匹配组内行数 cycle = list(range(1, interval_val + 1)) return cycle * (len(group) // interval_val) + cycle[:len(group) % interval_val] # 应用函数并展开结果 Table['Counter'] = Table.groupby('group').apply(get_counter).explode().reset_index(drop=True)
或者用更简洁的transform写法:
Table['Counter'] = Table.groupby('group').transform( lambda x: [(i % x.iloc[0]) + 1 for i in range(len(x))] ).explode()
最终结果
执行后Table的内容:
| Row | Intervals | group | Counter |
|---|---|---|---|
| 0 | 2 | 1 | 1 |
| 1 | 2 | 1 | 2 |
| 2 | 2 | 1 | 1 |
| 3 | 2 | 1 | 2 |
| 4 | 3 | 2 | 1 |
| 5 | 3 | 2 | 2 |
| 6 | 3 | 2 | 3 |
| 7 | 2 | 3 | 1 |
| 8 | 2 | 3 | 2 |
Counter列完全符合预期值。
内容的提问来源于stack exchange,提问作者Naor
相关产品推荐
相关产品推荐

