如何对比DataFrame的sheetnumber列与指定列表并提取列表中不存在的元素
从指定列表中提取未在DataFrame
sheetnumber列出现的元素 核心注意点
做这类交叉比对最容易踩的坑就是类型不匹配:示例里的待对比列表是字符串格式,而DataFrame的sheetnumber列默认是浮点数值类型,直接拿两边的值做匹配,会因为类型对不上把所有元素都判定为不存在,最后跑出来的结果完全不对。
实现思路
- 先把两边待比对的元素类型拉齐:把DataFrame的
sheetnumber列所有值转成和待对比列表一致的字符串格式,存在集合里。集合的存在性查找是O(1)复杂度,比逐行扫描DataFrame快非常多,尤其是数据量上去之后差异特别明显。 - 遍历待对比列表,把不在上述集合里的元素筛选出来,就是最终要的结果。
可运行示例代码
import pandas as pd # 构造示例DataFrame df = pd.DataFrame({ 'sheetnumber': [682.11, 682.12, 682.13, 682.14, 682.15, 783.4] }) # 注意不要用list当变量名(这是Python内置关键字,会覆盖原生的列表生成方法) target_list = ['682.9', '682.12', '682.11', '682.13', '682.14', '682.15'] # 把DataFrame的sheetnumber列值统一转成字符串,构建比对用的集合 existing_sheets = set(df['sheetnumber'].astype(str)) # 筛选目标列表中未在DataFrame出现的元素 result = [item for item in target_list if item not in existing_sheets]
运行后得到的result值与预期完全一致:
['682.9']
常见坑补充
- 如果DataFrame里的浮点数是经过计算存储的,可能存在微小的精度偏差,比如本来应该是682.11的数值被存成了682.1099999,直接转字符串后会和目标列表的字符串匹配不上。碰到这种情况可以在转字符串前先对列值做固定小数位的处理,比如使用
df['sheetnumber'].round(2).astype(str)完成格式转换,规避精度误差的影响。 - 别图省事直接写
item not in df['sheetnumber'],当DataFrame有几万行的时候,这种写法的运行速度会比集合比对慢几十倍,数据量越大效率差距越夸张。
内容的提问来源于stack exchange,提问作者Rajisakthi
相关产品推荐
相关产品推荐

