如何基于布尔条件删除MultiIndex多层索引DataFrame切片中的指定行
问题根因
你的代码运行后全为NaN是因为pandas的索引对齐机制:你对data.loc[idx](对应该run下的所有step行)赋值时,右侧筛选后的结果仅包含符合条件的部分行,赋值时pandas会按照两边的step索引自动对齐,右侧不存在的step对应位置就会被填充为NaN。
而data.loc[idx].drop(..., inplace=True)不生效是因为data.loc[idx]返回的是原DataFrame的切片副本,对副本的inplace修改不会作用到原data表上。
另外你提供的测试表生成代码末尾有一个多余的右括号,运行前需要删除才能正常生成测试数据。
解决方法
方法1:合并+筛选(推荐,无循环,性能更优)
不需要写循环,直接通过表关联和筛选实现需求,适合大数据量场景:
import pandas as pd # 1. 将data的多级索引转为普通列,方便关联匹配 data_reset = data.reset_index() # 2. 和valid_range按照run字段关联 merged = data_reset.merge(valid_range, on="run") # 3. 筛选满足step在[start, stop]区间的行 filtered = merged[(merged["step"] >= merged["start"]) & (merged["step"] <= merged["stop"])] # 4. 还原为原表结构,删除多余字段并恢复多级索引 result = filtered.drop(columns=["start", "stop"]).set_index(["run", "step"])
方法2:循环筛选后拼接
如果更习惯循环写法,可以收集每个run符合条件的切片后合并:
import pandas as pd res_list = [] for run_id in valid_range.index: start, stop = valid_range.loc[run_id] # 筛选当前run符合条件的行 run_data = data.loc[run_id].loc[start:stop].reset_index() run_data.insert(0, "run", run_id) res_list.append(run_data) # 拼接所有结果并恢复多级索引 result = pd.concat(res_list).set_index(["run", "step"])
运行以上任意一种方法,得到的result就是处理后的符合要求的表。
内容的提问来源于stack exchange,提问作者Hyperplane
相关产品推荐
相关产品推荐

