You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Pandas Series的条件触发列表索引递增生成新序列

问题描述

给定以下Pandas Series:

import pandas as pd
s = pd.Series(['01','02','03','01','02','03','01','02','03'])

以及列表:

l = ['A','B','C']

需求:每当Series中出现'01'时,推进列表的索引,后续元素填充为对应索引的列表值,最终得到目标Series:

pd.Series(['A','A','A','B','B','B','C','C','C'])

尝试用apply方法实现,但逻辑存在问题,当前代码:

s.apply(increment)

def increment(s):
   l = ['A','B','C']
   count = 0
   if s == '01':
     count += 1
     # 此处无法正确处理索引推进逻辑
     return l[count]
解决方案

你的apply写法核心问题是:每次调用increment时,count都会被重新初始化为0,无法持续追踪索引的推进状态。以下是两种可行的实现方式:

方法1:利用cumsum分组映射(推荐)

这种方法符合Pandas向量化操作的风格,效率更高:

import pandas as pd

s = pd.Series(['01','02','03','01','02','03','01','02','03'])
l = ['A','B','C']

# 生成分组标记:遇到'01'就累加1,最终得到分组ID
group_ids = (s == '01').cumsum() - 1  # 减1让索引从0开始匹配列表l
result = pd.Series([l[i] for i in group_ids])

逻辑说明

  • s == '01'生成布尔数组,遇到'01'时为True(即1),其余为0
  • cumsum()累计求和后得到[1,1,1,2,2,2,3,3,3],减1后转为[0,0,0,1,1,1,2,2,2],正好对应列表l的索引
  • 通过列表推导式将分组ID映射为目标值,得到最终结果

方法2:带状态的闭包实现(类似apply思路)

如果一定要用类似apply的方式,需要用闭包保存count的状态,避免每次调用重置:

import pandas as pd

s = pd.Series(['01','02','03','01','02','03','01','02','03'])
l = ['A','B','C']

def create_incrementer():
    count = 0
    def incrementer(val):
        nonlocal count
        if val == '01':
            count += 1
        # 第一次遇到'01'后count变为1,减1对应l的索引0
        return l[count - 1]
    return incrementer

result = s.apply(create_incrementer())

逻辑说明

  • create_incrementer是闭包函数,内部的count会被incrementer持续引用,不会每次调用都重置
  • 每遇到'01'时count加1,后续元素都会使用当前count-1对应的列表值,直到下一个'01'出现

验证结果

运行上述代码后,输出结果如下:

0    A
1    A
2    A
3    B
4    B
5    B
6    C
7    C
8    C
dtype: object

内容的提问来源于stack exchange,提问作者INGl0R1AM0R1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:45:46