如何高效获取DataFrame列表列对应Series的索引并新增列?
如何高效获取DataFrame列表列对应Series的索引并新增列?
问题分析
你原来使用的嵌套apply方法性能低下的核心原因是双重线性遍历:对DataFrame的每一行,都要完整遍历整个Series去匹配列表是否相等,时间复杂度为O(len(df) * len(ps))。当数据量庞大时,这种方法的耗时会随数据规模呈指数级增长,完全无法支撑高效处理。
高效解决方案:利用哈希映射(字典)实现O(1)查找
我们可以通过哈希字典将列表-索引的匹配从线性查找转为常数时间查找,整体时间复杂度降至O(len(ps) + len(df)),性能会得到质的提升。核心思路是先把Series的内容预存为可快速查询的映射关系,再一次性完成DataFrame的匹配。
步骤1:构建元组到索引的映射字典
由于列表是不可哈希的类型,无法直接作为字典的键,我们先将Series中的每个列表转换为可哈希的元组,创建"元组-对应索引"的映射字典:
# 构建元组到索引的快速映射 map_dict = {tuple(val): idx for idx, val in ps.items()}
步骤2:批量匹配DataFrame中的列表并获取索引
将DataFrame的a列中的每个列表转为元组,通过字典的O(1)查找快速得到对应索引:
# 为DataFrame新增idx列 df['idx'] = df['a'].apply(lambda x: map_dict[tuple(x)])
或者用更简洁的map写法:
df['idx'] = df['a'].map(lambda x: map_dict[tuple(x)])
结果验证
执行上述代码后,你的DataFrame会完全符合预期输出:
a idx 0 [a, b, c] 0 1 [a, c, b] 1 2 [c, a, b] 4
异常处理(可选)
如果DataFrame的a列中存在Seriesps里没有的列表,直接查找会触发KeyError。你可以用dict.get()方法设置默认值来避免报错,比如将不存在的项索引设为-1:
# 新增默认值,避免不存在的列表触发报错 df['idx'] = df['a'].apply(lambda x: map_dict.get(tuple(x), -1))
性能优势说明
这种方法的高效性体现在:
- 构建字典仅需遍历Series一次,时间复杂度
O(len(ps)) - 每个列表的索引查找都是常数时间
O(1),遍历DataFrame的时间复杂度O(len(df)) - 整体性能几乎不受DataFrame和Series规模增长的影响,即使数据量增长100倍,耗时也只会线性增加,远优于嵌套
apply的低效遍历。
备注:内容来源于stack exchange,提问作者Sun Jar
相关产品推荐
相关产品推荐

