python - 从 Pandas DataFrame 中删除许多索引范围
问题描述
问题+ MWE
如何从具有(两级)多索引的 Pandas DataFrame 中删除/删除多个行范围,如下所示:
idx1 idx2 | value(s) ...
------------------------------------------
4 0 | 1.123456 ...
1 | 2.234567 ...
2 | 0.012345 ...
8 0 | -1.123456 ...
1 | -0.973915 ...
2 | 1.285553 ...
3 | -0.194625 ...
4 | -0.144112 ...
... ... | ... ...
要删除/删除的范围当前位于如下列表中:
ranges = [[(4, 1), (4, 2)], # range (4,1):(4,2)
[(8, 0), (8, 3)], # range (8,0):(8,3)
[(8, 5), (8, 10)], ...] # range (8,5):(8,10)
主要问题是,我发现的大多数方法都不支持多索引或切片或多个切片/范围。
最好/最快的方法是什么。
当前丑陋的解决方案
for range in ranges:
df = df.drop(df.loc[range[0]:range[1]].index)
缓慢而丑陋,但它是我发现的唯一可行的解决方案,它结合了多索引、切片和多个范围(通过循环范围)。
方案比较
所有三个提议的解决方案都有效。他们都通过将切片列表转换为这些切片中所有单个元组的列表来解决问题。
切片以完成一组元组
最快的方法是@ALollz 解决方案:
idx = [(x, z) for (x, i), (_, j) in ranges for z in np.arange(i,j+1,1)]
表现
关于删除行,所有解决方案都有效,但性能存在很大差异(所有性能数据均基于我的数据集,包含约 10 个 Mio. 条目)
@ALollz + @Ben。T 的组合解决方案(~19 秒)
df.drop(pd.MultiIndex.from_tuples(idx))
或不创建
MultiIndex
对象df.drop(idx)
@ALollz 第一个解决方案(~75 秒。)
df.loc[list(set(df.index.values) - set(idx))]
@user3471881 的解决方案(~95 秒)
df.loc[~df.index.isin(ranges)]
我丑陋的解决方案(〜350秒。)
see above
解决方案
您可以创建一个新的索引列表,正如 Ben.T 指出的那样,只需删除它们。
import numpy as np
import pandas as pd
idx = [(x, z) for (x, i), (_, j) in ranges for z in np.arange(i,j+1,1)]
df.drop(pd.MultiIndex.from_tuples(idx))
输出:
value(s)
idx1 idx2
4 0 4
8 4 11
推荐阅读
- mysql - 两个日期之间的mysql选择有奇怪的行为
- python - 如何使用 while 收集结果值?
- android - android.intent.category.DEFAULT 和 android.intent.category.PREFERENCE 有什么不同?
- sangria - 如何使用 Sangria 的 `@GraphQLField` 注释创建嵌套的 GraphQL 字段
- angular - Ionic 自定义现有的 UI 组件
- http2 - 阻止来自允许 URL 的脚本
- c# - Visual Studio 2017 详细发布
- loops - Lisp - 标志(班德拉)不起作用
- pdf - 如何恢复损坏的pdf
- signalr - 使用 Aspnetcore.signalr libray 从集线器外部获取 HubContext(不是来自控制器)