如何将含零与重复值的Pandas列表列转换为指定规则的索引列表
问题:处理Pandas列表列的自定义升序顺序值生成
需求规则
- 原列表中的零在结果列表中仍保留为0;
- 非零值的顺序值从1开始;
- 重复的非零值分配相同的顺序值,后续值的序号需跳过对应重复次数(例如2个重复值,下一个序号+2;3个重复值则+3)。
现有代码
import pandas as pd df = pd.DataFrame({'original_list': [[1.8, 8.3, 8.6, 20.8, 34.7, 8.6, 5.7, 29.7], [0, 1, 2, 2, 2, 4, 6, 7, 0, 3, 3]]}) df['order_list'] = df['original_list'].apply(lambda x: [0 if elem == 0 else sorted(range(len(x)), key=lambda i: (x[i], i))[:x.count(elem)].index(x.index(elem)) + 1 for elem in x])
当前输出
0 [0, 2, 3, 5, 7, 3, 1, 6] 1 [0, 2, 3, 3, 3, 8, 9, 10, 0, 6, 6]
期望输出
0 [1, 3, 4, 6, 8, 4, 2, 7] 1 [0, 1, 2, 2, 2, 7, 8, 9, 0, 5, 5]
问题分析
原有代码逻辑错误:
- 使用
x.index(elem)会取元素第一次出现的索引,无法匹配当前位置的元素; - 未正确按重复次数累加序号,导致非零值起始序号错误,且重复值后的序号未正确跳过对应次数。
解决方案
自定义处理函数
编写一个函数,先对非零元素排序并分配符合规则的序号,再映射回原列表:
import pandas as pd def generate_order_list(lst): # 提取非零元素及其原始索引 non_zero_items = [(val, idx) for idx, val in enumerate(lst) if val != 0] # 按值升序,值相同则按原始索引升序排序 sorted_non_zero = sorted(non_zero_items, key=lambda item: (item[0], item[1])) # 为每个唯一非零值分配对应的序号 value_order_map = {} current_seq = 1 i = 0 total_non_zero = len(sorted_non_zero) while i < total_non_zero: current_val = sorted_non_zero[i][0] # 统计当前值的重复次数 repeat_count = 0 while i + repeat_count < total_non_zero and sorted_non_zero[i + repeat_count][0] == current_val: repeat_count += 1 # 记录当前值对应的序号 value_order_map[current_val] = current_seq # 下一个序号累加重复次数 current_seq += repeat_count i += repeat_count # 生成最终结果列表 return [0 if val == 0 else value_order_map[val] for val in lst] # 应用函数到DataFrame df = pd.DataFrame({'original_list': [[1.8, 8.3, 8.6, 20.8, 34.7, 8.6, 5.7, 29.7], [0, 1, 2, 2, 2, 4, 6, 7, 0, 3, 3]]}) df['order_list'] = df['original_list'].apply(generate_order_list)
验证输出
运行后得到的df['order_list']结果与期望输出一致:
0 [1, 3, 4, 6, 8, 4, 2, 7] 1 [0, 1, 2, 2, 2, 7, 8, 9, 0, 5, 5]
内容的提问来源于stack exchange,提问作者apk19
相关产品推荐
相关产品推荐

