使用部分索引元组列表对多索引数据帧进行切片的最佳方法是什么?
What is the best way to slice a multiindex dataframe using a list of partial index tuples?
我想使用部分匹配的索引或元组列表对数据帧进行切片。
_ix = [('foo','a', 1), ('foo','a', 2), ('foo','b', 1),
('foo','b', 2), ('foo','c', 1), ('foo','c', 2)]
df = pd.DataFrame(np.ones((6, 1)), index=pd.MultiIndex.from_tuples(_ix))
print(df)
0
foo a 1 1.0
2 1.0
b 1 1.0
2 1.0
c 1 1.0
2 1.0
给定查询索引,如:
q_ix = [('foo', 'a'), ('foo', 'c')]
我要获取
0
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0
我可以通过使用pd.concat
和列表理解得到这个...
df_sliced = pd.concat([df.loc[(*x, slice(None)), :] for x in q_ix])
...但是当我的查询索引很大时,这非常笨拙。有没有更好的办法?
这是一种方法
df.reset_index(level=2).loc[q_ix].set_index('level_2',append=True)
0
level_2
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0
使用 pd.IndexSlice
来自 pandas
import pandas as pd
idx = pd.IndexSlice
df.loc[idx[:, ['a', 'c']], :] # Can use 'foo' instead of : on the first lvl
产出
0
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0
它读取了第一层 (:
) 的所有内容,然后在第二层获取 ["a", "c"]
。我们将其包含在 idx
中以标记它是一个切片。最后,最后一个 :
告诉我们想要所有的列。
您可以尝试在面具上使用 index.droplevel
和 isin
,以及 .loc
n = df.index.droplevel(2).isin(q_ix)
Out[75]: array([ True, True, False, False, True, True])
df.loc[n]
Out[76]:
0
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0
我想使用部分匹配的索引或元组列表对数据帧进行切片。
_ix = [('foo','a', 1), ('foo','a', 2), ('foo','b', 1),
('foo','b', 2), ('foo','c', 1), ('foo','c', 2)]
df = pd.DataFrame(np.ones((6, 1)), index=pd.MultiIndex.from_tuples(_ix))
print(df)
0
foo a 1 1.0
2 1.0
b 1 1.0
2 1.0
c 1 1.0
2 1.0
给定查询索引,如:
q_ix = [('foo', 'a'), ('foo', 'c')]
我要获取
0
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0
我可以通过使用pd.concat
和列表理解得到这个...
df_sliced = pd.concat([df.loc[(*x, slice(None)), :] for x in q_ix])
...但是当我的查询索引很大时,这非常笨拙。有没有更好的办法?
这是一种方法
df.reset_index(level=2).loc[q_ix].set_index('level_2',append=True)
0
level_2
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0
使用 pd.IndexSlice
来自 pandas
import pandas as pd
idx = pd.IndexSlice
df.loc[idx[:, ['a', 'c']], :] # Can use 'foo' instead of : on the first lvl
产出
0
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0
它读取了第一层 (:
) 的所有内容,然后在第二层获取 ["a", "c"]
。我们将其包含在 idx
中以标记它是一个切片。最后,最后一个 :
告诉我们想要所有的列。
您可以尝试在面具上使用 index.droplevel
和 isin
,以及 .loc
n = df.index.droplevel(2).isin(q_ix)
Out[75]: array([ True, True, False, False, True, True])
df.loc[n]
Out[76]:
0
foo a 1 1.0
2 1.0
c 1 1.0
2 1.0