HDFStore.remove 说删了 3 行,实际却少了 5 行
pandas 的 HDF table 删除路径可能把排序后的旧标签当成位置,非升序坐标会误删其他行。暂停原件写入,在备份副本中核对坐标、排序去重和剩余记录。
store.remove("x", where=[5, 1, 2]) 返回 3,表里却少了原先位置 1 到 5 的五行。不要继续用另一组坐标在同一个文件上试;先暂停写入并保留当前文件和最近可信备份。
pandas 3.0.6、PyTables 3.11.1 有这个明确表现,3.1.0 正式删除实现仍保留相关分组逻辑。非升序列表、NumPy 数组或 Index 都可能触发;同一组升序坐标 [1, 2, 5] 则可以走出正确结果。返回值来自请求坐标数量,不足以证明实际删除范围正确。
排序后的标签被当作了位置
HDF table 的删除实现先把坐标放进 Series 并排序,排序保留原标签;随后用差值找到连续分组边界,又把那些标签当作排序后的位置。输入本来已排序时,两者碰巧一致;乱序时就可能把不相邻的行误并成连续删除范围。
这里的坐标是 HDF table 的物理行位置,不是 DataFrame 业务索引标签。where=[5, 1, 2] 不能按“删除索引值为 5、1、2”理解。先核对坐标来自什么快照、是否属于同一个 key,避免在已经删除过行的文件里继续使用旧位置。
只在独立副本中验证删除计划
原始文件保留不动,先建立可验证、未被其他进程同时写入的备份副本。在待验证副本中,明确将合法整数坐标排序、去重,再按原删除入口执行。例如坐标规划可以写为:
coordinates = [5, 1, 2]
planned_coordinates = sorted(set(coordinates))
这段代码只生成删除计划,不打开或修改 HDF 文件。实际提交前仍要验证每项确实是整数行位置、没有布尔值或越界值,记录这些位置对应的业务主键,并核对原表行数。不能把任意混合类型列表交给排序后就宣称安全。
在副本完成删除后,比较剩余主键集合、被删主键集合、行数与未涉及字段,而不只是检查 remove 的返回值。验证成立后才按应用现有维护流程安排正式操作;文件锁、写入方和恢复窗口仍应由该流程管理。
错删不能靠再次 remove 恢复
行被删除以后,后面的物理位置会变化;重复原操作可能继续删除另一批数据。不要用补插几行的临时方式猜测恢复,特别是表含索引、压缩、数据列或其他元数据时。
需要从可信备份或原始记录恢复时,先在新文件中重建并完整核对,再按原切换流程替换;当前错误文件也保留为诊断材料。没有可用原件时,应明确哪些记录已经无法从现有文件可靠恢复。
采用后续正式修正时,保留升序、乱序、相邻与不相邻坐标的对照,并检查真实剩余数据。字符串条件可能经过已排序的坐标查询路径,但它必须表达同一个业务删除集合,不能为了绕过问题随意改写条件或忽略原有权限约束。


