如何在无循环时为Pandas DataFrame生成分组递增标识列?
当然有无需循环的实现方式!
完全不用写繁琐的循环,Pandas提供了两种简洁的向量化操作方案,完美匹配你的需求:
方案一:用pd.factorize()(最省心的选择)
factorize()就是干这个活的——它会自动把你的name列里的唯一值按首次出现顺序映射成从0开始的连续整数,相同的字符串会得到相同的编码,正好完全符合你的预期。
直接上代码:
import pandas as pd # 构建你的示例DataFrame df = pd.DataFrame({'name': ['str_a', 'str_a', 'str_a', 'str_b', 'str_b', 'str_c', 'str_c']}) # 一键生成number列 df['number'] = pd.factorize(df['name'])[0]
运行后直接得到你要的结果:
| name | number |
|---|---|
| str_a | 0 |
| str_a | 0 |
| str_a | 0 |
| str_b | 1 |
| str_b | 1 |
| str_c | 2 |
| str_c | 2 |
方案二:用shift() + cumsum()(手动实现逻辑,适合理解原理)
如果你想搞清楚背后的逻辑,可以手动实现“行值变化时加1”的规则:
- 用
shift()获取前一行的name值,和当前行对比生成布尔序列(标记是否进入新分组) - 对布尔序列累加(True会被当1,False当0),再减1就能得到从0开始的编码
代码示例:
# 标记是否是新分组的起始行 df['new_group'] = df['name'] != df['name'].shift() # 累加后减1得到number列 df['number'] = df['new_group'].cumsum() - 1 # 可选:删除中间辅助列 df.drop('new_group', axis=1, inplace=True)
这个方法的结果和方案一完全一致,适合你理解底层的向量化操作逻辑。
内容的提问来源于stack exchange,提问作者Pi-R
相关产品推荐
相关产品推荐

