MultiIndex
API多年来一直受到欢迎,但是,就结构,工作和相关操作而言,并不是所有有关它的内容都被完全理解。
一项重要的操作是过滤。过滤是一个常见的要求,但是用例是多种多样的。因此,某些方法和功能将比其他方法和功能更适用于某些用例。
总而言之,本文旨在解决一些常见的过滤问题和用例,演示解决这些问题的各种不同方法,并讨论其适用性。这篇文章试图解决的一些高级问题是
这些问题已分解为6个具体问题,如下。为简单起见,下面设置中的示例DataFrame仅具有两个级别,并且没有重复的索引键。针对该问题提出的大多数解决方案可以推广到N个级别。
本文将不介绍如何创建MultiIndexes,如何对它们执行赋值操作或任何与性能相关的讨论(这些是下次的单独主题)。
将根据以下设置询问问题1-6。
mux = pd.MultiIndex.from_arrays([ list('aaaabbbbbccddddd'), list('tuvwtuvwtuvwtuvw') ], names=['one', 'two']) df = pd.DataFrame({'col': np.arange(len(mux))}, mux) col one two a t 0 u 1 v 2 w 3 b t 4 u 5 v 6 w 7 t 8 c u 9 v 10 d w 11 t 12 u 13 v 14 w 15
问题1::选择单个项目
如何选择在“一个”级别中具有“ a”的行?
col
one two
a t 0
u 1
v 2
w 3
另外,我如何在输出中将级别“ one”降低?
col
two
t 0
u 1
v 2
w 3
问题1b
如何在级别“ two”上切片所有值为“ t”的行?
col
one two
a t 0
b t 4
t 8
d t 12
问题2::在一个级别中选择多个值
如何在级别“ one”中选择与项目“ b”和“ d”相对应的行?
col
one two
b t 4
u 5
v 6
w 7
t 8
d w 11
t 12
u 13
v 14
w 15
问题2b
我如何获得与“两个”级别中的“ t”和“ w”相对应的所有值?
col
one two
a t 0
w 3
b t 4
w 7
t 8
d w 11
t 12
w 15
问题3::将单个横截面切成(x, y)
如何从df
检索横截面,即具有特定索引值的一行?具体来说,如何获取{p>给出的('c', 'u')
的横截面
col
one two
c u 9
问题4::切片多个横截面[(a, b), (c, d), ...]
如何选择与('c', 'u')
和('a', 'w')
对应的两行?
col
one two
c u 9
a w 3
问题5:每级切成一个项目
如何检索与“一个”级别中的“ a”或“第二”级别中的“ t”相对应的所有行?
col
one two
a t 0
u 1
v 2
w 3
b t 4
t 8
d t 12
问题6:任意切片
如何切特定的横截面?对于“ a”和“ b”,我想选择子级别为“ u”和“ v”的所有行,对于“ d”,我想选择子级别为“ w”的行。>
col
one two
a u 1
v 2
b u 5
v 6
d w 11
w 15
问题7将使用由数字级别组成的独特设置:
np.random.seed(0) mux2 = pd.MultiIndex.from_arrays([ list('aaaabbbbbccddddd'), np.random.choice(10, size=16) ], names=['one', 'two']) df2 = pd.DataFrame({'col': np.arange(len(mux2))}, mux2) col one two a 5 0 0 1 3 2 3 3 b 7 4 9 5 3 6 5 7 2 8 c 4 9 7 10 d 6 11 8 12 8 13 1 14 6 15
问题7:在数字级别进行基于不等式的过滤
如何获得“二级”中的值大于5的所有行?
col
one two
b 7 4
9 5
c 7 10
d 6 11
8 12
8 13
6 15
答案 0 :(得分:2)
答案 1 :(得分:0)
最近,我遇到一个用例,其中有一个3级以上的多索引数据框,在其中我无法使上面的任何解决方案产生想要的结果。上面的解决方案很可能确实可以在我的用例中使用,我尝试了几种,但是我无法在有空的时候让它们使用。
我距离专家还很远,但是我偶然发现了上面综合答案中未列出的解决方案。我不保证解决方案在任何方面都是最佳的。
这是获得与上面问题#6稍有不同的结果的不同方法。 (以及其他可能的问题)
特别是我在寻找:
作为齿轮上的活动扳手(但是完全可以固定):
在下面的玩具数据框中:
index = pd.MultiIndex.from_product([['a','b'],
['stock1','stock2','stock3'],
['price','volume','velocity']])
df = pd.DataFrame([1,2,3,4,5,6,7,8,9,
10,11,12,13,14,15,16,17,18],
index)
0
a stock1 price 1
volume 2
velocity 3
stock2 price 4
volume 5
velocity 6
stock3 price 7
volume 8
velocity 9
b stock1 price 10
volume 11
velocity 12
stock2 price 13
volume 14
velocity 15
stock3 price 16
volume 17
velocity 18
当然,使用以下作品:
df.xs(('stock1', 'velocity'), level=(1,2))
0
a 3
b 12
但是我想要一个不同的结果,所以获得该结果的方法是:
df.iloc[df.index.isin(['stock1'], level=1) &
df.index.isin(['velocity'], level=2)]
0
a stock1 velocity 3
b stock1 velocity 12
如果我想从一个级别获得两个以上的值,并从另一个级别获得一个(或2个以上)值:
df.iloc[df.index.isin(['stock1','stock3'], level=1) &
df.index.isin(['velocity'], level=2)]
0
a stock1 velocity 3
stock3 velocity 9
b stock1 velocity 12
stock3 velocity 18
上面的方法可能有点笨拙,但是我发现它可以满足我的需求,而且奖金对我来说更易于理解和阅读。