根据级别之间的 'AND' 条件删除 DataFrame 的多索引行
Drop multi-indexed rows of a DataFrame based on 'AND' condition between levels
我希望能够使用多级标准(使用逻辑 AND 加入标准)从多索引数据框对象中删除行。
考虑以下 pandas 数据框对象:
import pandas as pd
df = pd.DataFrame(data = [[1,'x'],[2,'x'],[1,'y'],[2,'y']],
index=pd.MultiIndex(levels=[['A','B'],['a','b']],
labels=[[0,1,0,1],[0,1,1,0]],
names=['idx0','idx1']))
print(df)
输出:
0 1
idx0 idx1
A a 1 x
B b 2 x
A b 1 y
B a 2 y
我想去掉'idx0'=='A'
和'idx1'=='a'
那一行,所以最后的结果是:
0 1
idx0 idx1
B b 2 x
a 2 y
A b 1 y
在我看来,这似乎不能用 df.drop()
方法来完成。 'roundabout' 给出正确结果的方法是:
df = pd.concat([df.drop(labels='A',level=0),df.drop(labels='a',level=1)])
df = df.drop_duplicates()
但我认为必须有更好的方法...
您可以使用 isin
方法进行索引,并与您使用 ~
选择的内容相反:
In [85]: df.index.isin([('A','a')])
Out[85]: array([ True, False, False, False], dtype=bool)
In [86]: df[~df.index.isin([('A','a')])]
Out[86]:
0 1
idx0 idx1
B b 2 x
A b 1 y
B a 2 y
时间:
In [95]: %timeit df.drop(('A','a'))
1000 loops, best of 3: 1.33 ms per loop
In [96]: %timeit df[~df.index.isin([('A','a')])]
1000 loops, best of 3: 457 us per loop
所以 drop 比 isin
解决方案慢了将近 3 倍。
要解决您关于 .drop()
的问题 - 只需将 MultiIndex
标签作为 tuple
:
df.drop(('A', 'a'))
0 1
idx0 idx1
B b 2 x
A b 1 y
B a 2 y
我希望能够使用多级标准(使用逻辑 AND 加入标准)从多索引数据框对象中删除行。
考虑以下 pandas 数据框对象:
import pandas as pd
df = pd.DataFrame(data = [[1,'x'],[2,'x'],[1,'y'],[2,'y']],
index=pd.MultiIndex(levels=[['A','B'],['a','b']],
labels=[[0,1,0,1],[0,1,1,0]],
names=['idx0','idx1']))
print(df)
输出:
0 1
idx0 idx1
A a 1 x
B b 2 x
A b 1 y
B a 2 y
我想去掉'idx0'=='A'
和'idx1'=='a'
那一行,所以最后的结果是:
0 1
idx0 idx1
B b 2 x
a 2 y
A b 1 y
在我看来,这似乎不能用 df.drop()
方法来完成。 'roundabout' 给出正确结果的方法是:
df = pd.concat([df.drop(labels='A',level=0),df.drop(labels='a',level=1)])
df = df.drop_duplicates()
但我认为必须有更好的方法...
您可以使用 isin
方法进行索引,并与您使用 ~
选择的内容相反:
In [85]: df.index.isin([('A','a')])
Out[85]: array([ True, False, False, False], dtype=bool)
In [86]: df[~df.index.isin([('A','a')])]
Out[86]:
0 1
idx0 idx1
B b 2 x
A b 1 y
B a 2 y
时间:
In [95]: %timeit df.drop(('A','a'))
1000 loops, best of 3: 1.33 ms per loop
In [96]: %timeit df[~df.index.isin([('A','a')])]
1000 loops, best of 3: 457 us per loop
所以 drop 比 isin
解决方案慢了将近 3 倍。
要解决您关于 .drop()
的问题 - 只需将 MultiIndex
标签作为 tuple
:
df.drop(('A', 'a'))
0 1
idx0 idx1
B b 2 x
A b 1 y
B a 2 y