在pandas MultiIndex DataFrame中选择行

数据帧的索引是MultiIndex的最常见的方法是什么?

  • 基于单个值/标签进行切片
  • 基于来自一个或多个级别的多个标签进行切片
  • 筛选布尔条件和表达式
  • 哪些方法适用于哪些情况

简单的假设:

  1. 输入数据帧没有重复的索引键
  2. 下面的输入数据帧只有两层。(这里显示的大多数解都泛化到N层)

示例输入:

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

此外,我如何能够在输出中删除级别“1”?

     col
two
t      0
u      1
v      2
w      3
< p > 问题1 b < br > 我如何在级别“2”上切片所有值为“t”的行?< / p >
         col
one two
a   t      0
b   t      4
t      8
d   t     12

问题2:在一个级别中选择多个值

如何在“一级”中选择与“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
< p > 问题2 b < br > 我如何在“第二层”中获得与“t”和“w”对应的所有值?< / p >
         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索引具有特定值的单行?具体来说,我如何检索('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:在多索引的各个层次上使用数值不等式进行过滤

我如何获得级别“2”中值大于5的所有行?

         col
one two
b   7      4
9      5
c   7     10
d   6     11
8     12
8     13
6     15

注意:这篇文章将介绍如何创建multiindex,如何对它们执行赋值操作,或任何与性能相关的讨论(这些是另一个单独的主题)。

103393 次浏览

MultiIndex /高级索引

< p > 请注意
这篇文章将以以下方式结构:

  1. OP中提出的问题将逐一得到解决
  2. 对于每个问题,将演示一种或多种适用于解决该问题并获得预期结果的方法。

请注意s(很像这个)将包括有兴趣了解额外功能,实现细节的读者, 以及其他与主题相关的粗略信息。这些笔记已经被 通过查阅文件和发现各种不为人知的 从我自己(诚然有限)的经验来看。

所有代码示例都已在Pandas v0.23.4, python3.7上创建并测试。如果有些事情不清楚,或者事实不正确,或者如果你没有 找到一个解决方案,适用于您的用例,请随时 建议编辑,在评论中要求澄清,或打开一个新的 问题,…适用。< / p >

下面介绍一些我们以后会经常用到的常用成语(以下简称“四大成语”)

  1. DataFrame.loc -根据标签选择的通用解决方案(+ pd.IndexSlice用于涉及切片的更复杂应用)

  2. DataFrame.xs -从Series/DataFrame中提取特定的横截面。

  3. DataFrame.query -动态指定切片和/或过滤操作(即,作为动态求值的表达式)。更适用于某些场景。也请参见这一部分的文档查询MultiIndexes。

  4. 使用MultiIndex.get_level_values生成的掩码进行布尔索引(通常与Index.isin结合使用,特别是在使用多个值进行过滤时)。这在某些情况下也非常有用。

从四个习语的角度来看各种切片和过滤问题将有助于更好地理解什么可以应用于给定的情况。重要的是要明白,并非所有的习语在每种情况下都同样有效(如果有的话)。如果一个习语没有被列为下面某个问题的潜在解决方案,那就意味着这个习语不能有效地应用于该问题。


问题1

我如何选择有“;a"在“一”级?

         col
one two
a   t      0
u      1
v      2
w      3

你可以使用loc,作为适用于大多数情况的通用解决方案:

df.loc[['a']]

此时,如果你得到

TypeError: Expected tuple, got str

这意味着你用的是熊猫的旧版本。考虑升级!否则,使用df.loc[('a', slice(None)), :]

或者,你可以在这里使用xs,因为我们提取的是单个横截面。注意levelsaxis参数(这里可以假设合理的默认值)。

df.xs('a', level=0, axis=0, drop_level=False)
# df.xs('a', drop_level=False)

这里,需要drop_level=False参数来防止xs删除level "one"在结果中(我们所切割的关卡)。

这里的另一个选项是使用query:

df.query("one == 'a'")

如果索引没有名称,则需要将查询字符串更改为"ilevel_0 == 'a'"

最后,使用get_level_values:

df[df.index.get_level_values('one') == 'a']
# If your levels are unnamed, or if you need to select by position (not label),
# df[df.index.get_level_values(0) == 'a']

此外,我如何才能降低关卡"one"在输出中?

     col
two
t      0
u      1
v      2
w      3

这可以用任意一个很容易来完成

df.loc['a'] # Notice the single string argument instead the list.

或者,

df.xs('a', level=0, axis=0, drop_level=True)
# df.xs('a')

注意,我们可以省略drop_level参数(默认情况下它被假设为True)。

< p > 请注意
你可能会注意到,一个过滤后的DataFrame可能仍然有所有的级别,即使它们在打印DataFrame时不显示。例如,< / p >
v = df.loc[['a']]
print(v)
col
one two
a   t      0
u      1
v      2
w      3


print(v.index)
MultiIndex(levels=[['a', 'b', 'c', 'd'], ['t', 'u', 'v', 'w']],
labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
names=['one', 'two'])

你可以使用< em > MultiIndex.remove_unused_levels < / em >来消除这些级别:

v.index = v.index.remove_unused_levels()
print(v.index)
MultiIndex(levels=[['a'], ['t', 'u', 'v', 'w']],
labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
names=['one', 'two'])

问题1 b

我如何切片所有行值"t"在“第二层”?

         col
one two
a   t      0
b   t      4
t      8
d   t     12

直观地说,你会想要一些涉及< em > slice() < / em >的东西:

df.loc[(slice(None), 't'), :]

它就是有用!™但它是笨拙的。在这里,我们可以使用pd.IndexSlice API来实现更自然的切片语法。

idx = pd.IndexSlice
df.loc[idx[:, 't'], :]

这个干净多了。

< p > 请注意
为什么需要跨列的尾部切片: ?这是因为,loc可用于沿两个轴(axis=0axis=1)。没有明确表示切片的哪个轴 是要做的,操作变得模糊。参见切片文档.

. 0中的大红色框

如果你想去除任何模糊的阴影,loc接受axis . b0 参数:< / p >

df.loc(axis=0)[pd.IndexSlice[:, 't']]
如果没有axis参数(即,仅通过执行df.loc[pd.IndexSlice[:, 't']]),则假定切片是在列上, ,在这种情况下将引发KeyError

这在切片机中有记录。然而,为了本文的目的,我们将显式地指定所有轴。

对于xs,它是

df.xs('t', axis=0, level=1, drop_level=False)

对于query,它是

df.query("two == 't'")
# Or, if the first level has no name,
# df.query("ilevel_1 == 't'")

最后,使用get_level_values,你可以这样做

df[df.index.get_level_values('two') == 't']
# Or, to perform selection by position/integer,
# df[df.index.get_level_values(1) == 't']

都是一样的效果。


问题2

我如何选择与项目"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

使用loc,可以通过指定一个列表以类似的方式完成此操作。

df.loc[['b', 'd']]

为了解决上述选择"b"和"d",你也可以使用query:

items = ['b', 'd']
df.query("one in @items")
# df.query("one == @items", parser='pandas')
# df.query("one in ['b', 'd']")
# df.query("one == ['b', 'd']", parser='pandas')
< p > 请注意
是的,默认的解析器是'pandas',但重要的是要强调这种语法不是常规的python。的 Pandas解析器生成的解析树与 表达式。这样做是为了使一些操作更加直观 指定。更多信息,请阅读我的帖子 利用pd.eval()计算熊猫的动态表达式 . < / p >

并且,使用get_level_values + Index.isin:

df[df.index.get_level_values("one").isin(['b', 'd'])]

问题2 b

我如何得到所有对应于"t"和“;w"在“第二”级?

         col
one two
a   t      0
w      3
b   t      4
w      7
t      8
d   w     11
t     12
w     15

对于loc,可以将只有pd.IndexSlice结合使用。

df.loc[pd.IndexSlice[:, ['t', 'w']], :]

pd.IndexSlice[:, ['t', 'w']]中的第一个冒号:表示横切第一层。随着所查询级别的深度增加,您将需要指定更多的切片,每个级别都被切片。但是,您不需要指定更多的级别除了

对于query,这是

items = ['t', 'w']
df.query("two in @items")
# df.query("two == @items", parser='pandas')
# df.query("two in ['t', 'w']")
# df.query("two == ['t', 'w']", parser='pandas')

使用get_level_valuesIndex.isin(类似于上面):

df[df.index.get_level_values('two').isin(['t', 'w'])]

问题3

我如何检索一个横截面,即,有特定值的单行 df?具体来说,我如何找回十字架 ('c', 'u')的section,由

给出
         col
one two
c   u      9

通过指定键元组来使用loc:

df.loc[('c', 'u'), :]

或者,

df.loc[pd.IndexSlice[('c', 'u')]]
< p > 请注意
在这一点上,你可能会遇到这样的< em > PerformanceWarning < / em >:

PerformanceWarning: indexing past lexsort depth may impact performance.

这只是意味着你的索引没有排序。Pandas依赖于对索引进行排序(在本例中是按字典顺序排序,因为我们处理的是字符串值)以获得最佳搜索和检索。一个快速的解决办法就是整理你的 DataFrame提前使用< em > DataFrame.sort_index < / em >。如果您计划这样做,那么从性能角度来看,这是特别可取的 串联多个这样的查询:

df_sort = df.sort_index()
df_sort.loc[('c', 'u')]

你也可以使用< em > MultiIndex.is_lexsorted() < / em >来检查索引是否 是否排序。此函数返回相应的TrueFalse。 您可以调用此函数来确定是否进行额外排序

.

.

.

对于xs,这同样只是简单地传递一个元组作为第一个参数,所有其他参数设置为适当的默认值:

df.xs(('c', 'u'))

使用query,事情变得有点笨拙:

df.query("one == 'c' and two == 'u'")

你可以看到,这将是比较难推广的。但对于这个特殊的问题还是可以的。

对于跨越多个级别的访问,get_level_values仍然可以使用,但不建议使用:

m1 = (df.index.get_level_values('one') == 'c')
m2 = (df.index.get_level_values('two') == 'u')
df[m1 & m2]

问题4

如何选择对应于('c', 'u')('a', 'w')的两行?

         col
one two
c   u      9
a   w      3

使用loc,这仍然像下面这样简单:

df.loc[[('c', 'u'), ('a', 'w')]]
# df.loc[pd.IndexSlice[[('c', 'u'), ('a', 'w')]]]

使用query,你需要通过迭代你的横截面和级别来动态生成一个查询字符串:

cses = [('c', 'u'), ('a', 'w')]
levels = ['one', 'two']
# This is a useful check to make in advance.
assert all(len(levels) == len(cs) for cs in cses)


query = '(' + ') or ('.join([
' and '.join([f"({l} == {repr(c)})" for l, c in zip(levels, cs)])
for cs in cses
]) + ')'


print(query)
# ((one == 'c') and (two == 'u')) or ((one == 'a') and (two == 'w'))


df.query(query)

100%不推荐!但这是可能的。

< p > 如果我有多个层次呢?
这种情况下的一个选项是使用droplevel删除你没有检查的级别,然后使用isin测试成员资格,然后在最终结果上使用布尔索引
df[df.index.droplevel(unused_level).isin([('c', 'u'), ('a', 'w')])]

问题5

我怎么能检索所有行对应的"a"在“一级”;或 “t"在“第二”级?< / p >

         col
one two
a   t      0
u      1
v      2
w      3
b   t      4
t      8
d   t     12

这实际上很难用loc来做到,同时确保而且的正确性,同时还能保持代码的清晰性。df.loc[pd.IndexSlice['a', 't']]是不正确的,它被解释为df.loc[pd.IndexSlice[('a', 't')]](即选择一个横截面)。你可以用pd.concat来单独处理每个标签:

pd.concat([
df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])


col
one two
a   t      0
u      1
v      2
w      3
t      0   # Does this look right to you? No, it isn't!
b   t      4
t      8
d   t     12

但是你会注意到其中一行是重复的。这是因为该行同时满足两个切片条件,因此出现了两次。你需要做的是

v = pd.concat([
df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])
v[~v.index.duplicated()]

但是如果你的DataFrame本身就包含重复的索引(你想要的),那么这将不会保留它们。慎用

对于query,这非常简单:

df.query("one == 'a' or two == 't'")

对于get_level_values,这仍然很简单,但没有那么优雅:

m1 = (df.index.get_level_values('one') == 'a')
m2 = (df.index.get_level_values('two') == 't')
df[m1 | m2]

问题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

这是我添加的一个特殊情况,以帮助理解四个习语的适用性——在这种情况下,它们都不能有效工作,因为切片是非常特定的,并且不遵循任何真实的模式。

通常,这样的切片问题需要显式地将键列表传递给loc。其中一种方法是:

keys = [('a', 'u'), ('a', 'v'), ('b', 'u'), ('b', 'v'), ('d', 'w')]
df.loc[keys, :]

如果你想节省一些输入,你会发现切片有一个模式"a", "b"和它的子级别,所以我们可以将切片任务分成两个部分,并concat结果:

pd.concat([
df.loc[(('a', 'b'), ('u', 'v')), :],
df.loc[('d', 'w'), :]
], axis=0)

“;a&;;”切片规范和“;b"(('a', 'b'), ('u', 'v'))略干净,因为被索引的相同子级别对于每个级别都是相同的。


问题7

我如何得到所有的行,其中值在级别“;2;”;大于5?

         col
one two
b   7      4
9      5
c   7     10
d   6     11
8     12
8     13
6     15

这可以使用query来完成,

df2.query("two > 5")

get_level_values

df2[df2.index.get_level_values('two') > 5]
< p > 请注意
与此示例类似,我们可以使用这些构造基于任意条件进行筛选。一般来说,记住locxs是专门用于基于标签的索引,而queryget_level_values有助于构建一般的条件掩码 过滤。< / p >

奖金问题

如果我需要切片一个MultiIndex 怎么办?

实际上,这里的大多数解决方案也适用于列,只做了一些小更改。考虑:

np.random.seed(0)
mux3 = pd.MultiIndex.from_product([
list('ABCD'), list('efgh')
], names=['one','two'])


df3 = pd.DataFrame(np.random.choice(10, (3, len(mux))), columns=mux3)
print(df3)


one  A           B           C           D
two  e  f  g  h  e  f  g  h  e  f  g  h  e  f  g  h
0    5  0  3  3  7  9  3  5  2  4  7  6  8  8  1  6
1    7  7  8  1  5  9  8  9  4  3  0  3  5  0  2  3
2    8  1  3  3  3  7  0  1  9  9  0  4  7  3  2  7

您需要对四个成语进行以下更改,以使它们与列一起工作。

  1. 要使用loc切片,使用

     df3.loc[:, ....] # Notice how we slice across the index with `:`.
    

    或者,

     df3.loc[:, pd.IndexSlice[...]]
    
  2. 要适当地使用xs,只需传递参数axis=1

  3. 你可以直接使用df.columns.get_level_values访问列级别的值。然后你需要做一些类似的事情

     df.loc[:, {condition}]
    

    其中{condition}表示使用columns.get_level_values构建的一些条件。

  4. 要使用query,你唯一的选择是转置,查询索引,然后再次转置:

     df3.T.query(...).T
    

    不建议使用其他3个选项之一。

最近,我遇到了一个用例,我有一个3级以上的多索引数据框架,在这个用例中,我不能让上面的任何解决方案产生我想要的结果。上面的解决方案很可能对我的用例有效,我尝试了几个,但我无法在我可用的时间内让它们工作。

我不是专家,但我偶然发现了一个解决方案,上面的综合答案中没有列出。我不能保证这些解决方案在任何方面都是最优的。

这是一种不同的方法,可以得到与上面的问题6略有不同的结果。(可能还有其他问题)

我特别想找的是:

  1. 从索引的一个级别选择两个+值,从索引的另一个级别选择一个值的方法
  2. 在数据帧输出中保留前一个操作的索引值的方法。

就像齿轮上的活动扳手一样(尽管完全可以固定):

  1. 这些索引未具名。

在下面的玩具数据框架上:

    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

上面的方法可能有点笨拙,但我发现它满足了我的需求,而且对我来说更容易理解和阅读。

这看起来是dfsql的一个很好的例子

df.sql(<SQL select statement>)

https://github.com/mindsdb/dfsql

这里有一篇完整的文章:

https://medium.com/riselab/why-every-data-scientist-using-pandas-needs-modin-bringing-sql-to-dataframes-3b216b29a7c0

我长期使用并欣赏这个问题,以及@cs95的响应,它非常彻底,处理所有实例。类似于@r-a的答案,我也想找到一种方法来处理包含多个级别的多个索引。

我最终找到了一种方法来获得给定级别或指定索引的任意数量的切片,这能够处理上面提出的几个问题。这里的主要改进是不必为多个索引或切片解析出slice(None)或带有pd.IndexSlice:

import pandas as pd


def slice_df_by(df_, slice_by=["Oman", "Nairobi",], slice_idx='country'):
idxn = df_.index.names.index(slice_idx)
return df_.loc[tuple([slice(None)]*idxn +[slice_by] ), :]


gender = tuple(["male", "female"]*6)
thrown = tuple(["rock", "scissors", "paper"]*4)
country = tuple(["Nairobi", "Oman", "Djibouti", "Belize"]*3)
names = tuple(["Chris", "Pat", "Michele", "Thomy", "Musa", "Casey"]*2)


tuples = list(zip(gender, thrown, country, names))


idx = pd.MultiIndex.from_tuples(tuples,
names=["gender", "thrown", "country", "name"])


df = pd.DataFrame({'Count A': [12., 70., 30., 20.]*3,
'Count B': [12., 70., 30., 20.]*3}, index=idx)

这样做的好处是,你可以将这些调用的任意组合添加到函数slice_df_by中,以获得更复杂的切片,同时只使用索引名和值列表。

print(slice_df_by(df))


Count A  Count B
gender thrown   country name
female scissors Oman    Pat         70.0     70.0
paper    Oman    Casey       70.0     70.0
rock     Oman    Thomy       70.0     70.0
male   rock     Nairobi Chris       12.0     12.0
scissors Nairobi Musa        12.0     12.0
paper    Nairobi Michele     12.0     12.0

正如@r-a指出的那样,问题在于没有命名索引。有很多方法可以使用这里的方法来满足这一点,比如df.index.names = ["names", "for", "the", "indices"]或一些类似的方法:

idxz = lambda ixln=4: [chr(i) for i in np.arange(ixln)+65]
df.index.names = idxz(len(df.index.names))
print(idxz())
Out[132]: ['A', 'B', 'C', 'D']

一个选项是使用select_rows from pyjanitor:

# pip install pyjanitor
import pandas as pd
import janitor

问题1

我如何选择有“;a"在“一”级?

df.select_rows('a')
col
one two
a   t      0
u      1
v      2
w      3

此外,我如何才能降低关卡"one"在输出中?

df.select_rows('a').droplevel('one')
col
two
t      0
u      1
v      2
w      3

问题1 b

我如何切片所有行值"t"在“第二层”?

         col
one two
a   t      0
b   t      4
t      8
d   t     12

在这里使用字典,指定级别作为键,并传递标签以选择:

df.select_rows({'two':'t'})
col
one two
a   t      0
b   t      4
t      8
d   t     12

问题2

我如何选择与项目"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

因为选择是在一个层次上,传递一个标签列表:

df.select_rows(['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

问题2 b

我如何得到所有对应于"t"和“;w"在“第二”级?

         col
one two
a   t      0
w      3
b   t      4
w      7
t      8
d   w     11
t     12
w     15

使用字典:

df.select_rows({'two':['t','w']})
col
one two
a   t      0
b   t      4
t      8
d   t     12
a   w      3
b   w      7
d   w     11
w     15

问题3

我如何检索一个横截面,即,有特定值的单行 df?具体来说,我如何找回十字架 ('c', 'u')的section,由

给出
         col
one two
c   u      9

我们要跨越级别(水平,而不是垂直),需要一个元组:

# sort required to avoid lexsort performance warning
df.sort_index().select_rows(('c','u'))
col
one two
c   u      9

问题4

如何选择对应于('c', 'u')('a', 'w')的两行?

         col
one two
c   u      9
a   w      3

select_rows接受多个变量参数:

df.sort_index().select_rows(('c','u'), ('a','w'))
col
one two
c   u      9
a   w      3

问题5

我怎么能检索所有行对应的"a"在“一级”;或 “t"在“第二”级?< / p >

         col
one two
a   t      0
u      1
v      2
w      3
b   t      4
t      8
d   t     12
df.select_rows('a', {'two':'t'})
col
one two
a   t      0
u      1
v      2
w      3
t      0
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
df.sort_index().select_rows({'one':['a','b'], 'two':['u','v']}, ('d','w'))
col
one two
a   u      1
v      2
b   u      5
v      6
d   w     11
w     15

问题7

我如何得到所有的行,其中值在级别“;2;”;大于5?

         col
one two
b   7      4
9      5
c   7     10
d   6     11
8     12
8     13
6     15

使用字典,你可以传递一个函数,只要它可以在Index对象上求值:

df2.select_rows({'two': lambda df: df > 5})
col
one two
b   7      4
9      5
c   7     10
d   6     11
8     12
8     13
6     15

可以使用select_columns函数对列进行选择。还有一个通用的选择函数用于对行和列进行选择。

函数是可扩展的:让我们看看它是如何工作的@double0darbo答案:

df.select_rows({'country':['Oman', 'Nairobi']})
Count A  Count B
gender thrown   country name
female scissors Oman    Pat         70.0     70.0
paper    Oman    Casey       70.0     70.0
rock     Oman    Thomy       70.0     70.0
male   rock     Nairobi Chris       12.0     12.0
scissors Nairobi Musa        12.0     12.0
paper    Nairobi Michele     12.0     12.0

试着回答:

df.select_rows({1:'stock1', 2:'velocity'})
0
a stock1 velocity   3
b stock1 velocity  12


df.select_rows({1:['stock1','stock3'], 2:'velocity'})
0
a stock1 velocity   3
b stock1 velocity  12
a stock3 velocity   9
b stock3 velocity  18


df.select_rows({0:slice('a',None), 1:['stock1','stock3'], 2:'velocity'})
0
a stock1 velocity   3
stock3 velocity   9
b stock1 velocity  12
stock3 velocity  18