如何基于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),其余为0cumsum()累计求和后得到[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
相关产品推荐
相关产品推荐

