在 pandas MultiIndex DataFrame 中选择行

2024-12-11 08:47:00
admin
原创
138
摘要:问题描述:使用 pandas 选择/过滤索引为 MultiIndex 的数据框的行的最常见方法是什么?根据单个值/标签进行切片根据一个或多个级别的多个标签进行切片根据布尔条件和表达式进行过滤什么情况下适用哪些方法简单假设:输入数据框没有重复的索引键下面的输入数据框只有两个级别。(这里展示的大多数解决方案都推广...

问题描述:

使用 pandas 选择/过滤索引为 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

此外,我怎样才能在输出中删除级别“一”?

     col
two     
t      0
u      1
v      2
w      3

问题 1b

如何在级别“二”上对值为“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

问题 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?具体来说,如何检索 的横截面('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

注意:这篇文章不会介绍如何创建多重索引,如何对它们执行分配操作,或任何与性能相关的讨论(这些是另一个时间的单独主题)。


解决方案 1:

多索引/高级索引

注意:

本篇文章的结构如下:

  1. OP 中提出的问题将逐一得到解答

  2. 对于每个问题,将展示一种或多种适用于解决该问题并获得预期结果的方法。

对于有兴趣了解其他功能、实现细节和其他与当前主题相关的信息的读者,我们将提供注释(与此注释非常相似)。这些注释是通过仔细阅读文档并发现各种晦涩难懂的功能以及我自己(诚然有限)的经验编写而成的

所有代码示例均在pandas v0.23.4、python3.7上创建并测试。如果某些内容不清楚或事实上不正确,或者您没有找到适用于您的用例的解决方案,请随时建议编辑、在评论中请求澄清或提出新问题,...视情况而定。

以下是一些我们经常会用到的常见成语(以下称为“四大成语”)的介绍

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

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

  3. DataFrame.query- 动态指定切片和/或过滤操作(即作为动态评估的表达式。在某些情况下比其他情况更适用。另请参阅文档的此部分以了解有关多索引的查询。

  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

这意味着您正在使用旧版本的 pandas。请考虑升级!否则,请使用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在结果中丢弃“一级”(我们切片的级别)。

另一个选择是使用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']

此外,我怎样才能在输出中删除级别“一”?

     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)。

注意:

您可能会注意到,经过过滤的 DataFrame 可能仍具有所有级别,即使在打印 DataFrame 时未显示它们。例如,

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'])

您可以使用以下方法摆脱这些级别MultiIndex.remove_unused_levels

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'])

问题 1b

如何对级别“二”上值为“t”的所有行进行切片?

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

直观地讲,你会想要一些涉及以下内容的东西slice()

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

它真的管用!™ 但它很笨重。我们可以使用此处的 API 实现更自然的切片语法pd.IndexSlice

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

这更加干净。

注意为什么需要跨列的

尾部切片?这是因为,可用于选择并沿两个轴(或
)进行切片。如果不明确说明要在哪个轴上进行切片,操作就会变得模棱两可。请参阅切片文档中的大红框。:`locaxis=0axis=1`

如果您想消除任何歧义,loc请接受一个axis
参数:

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')

注意:

是的,默认解析器是'pandas',但需要强调的是,这种语法不是传统的 Python 语法。Pandas 解析器会生成与表达式略有不同的解析树。这样做是为了让某些操作更直观地指定。有关更多信息,请阅读我关于
使用 pd.eval() 在 pandas 中进行动态表达式求值的帖子。

并且,使用get_level_values+ Index.isin

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

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

,这只有与结合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'),如下所示

         col
one two     
c   u      9

loc通过指定一个键组来使用:

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

或者,

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

注意

此时,您可能会遇到PerformanceWarning如下情况:

PerformanceWarning: indexing past lexsort depth may impact performance.

这仅意味着您的索引未排序。pandas 依赖于排序的索引(在本例中按字典顺序排列,因为我们处理的是字符串值)以实现最佳搜索和检索。一个快速解决方法是使用 提前对 DataFrame 进行排序DataFrame.sort_index。如果您计划同时执行多个此类查询,从性能角度来看,这尤其可取:

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

您还可以使用它MultiIndex.is_lexsorted()来检查索引是否已排序。此函数相应地返回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%不推荐!但这是可能的。

如果我有多个级别怎么办?

在这种情况下,一个选项是使用droplevel删除您不检查的级别,然后使用isin测试成员资格,然后对最终结果进行布尔索引。

df[df.index.droplevel(unused_level).isin([('c', 'u'), ('a', 'w')])]

问题 5

我如何检索与“第一”级中的“a”或“第二”级中的“t”相对应的所有行?

         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

如何获取“第二”级中的值大于 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]

注意

与此示例类似,我们可以使用这些构造根据任意条件进行过滤。一般来说,记住locxs专门用于基于标签的索引很有用,而query
get_level_values有助于构建用于过滤的一般条件掩码。


奖励问题

如果我需要切分一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[...]]
  1. 如需适当使用xs,只需传递一个参数axis=1

  2. 您可以使用 直接访问列级别值df.columns.get_level_values。然后您需要执行类似以下操作

 df.loc[:, {condition}] 

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

  1. 要使用query,您唯一的选择是转置、在索引上查询,然后再次转置:

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

不推荐,使用其他 3 个选项之一。

解决方案 2:

最近我遇到了一个用例,我有一个 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

如果我想要从一个级别获取两个以上的值,并从另一个级别获取一个(或两个以上)值:

    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

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

解决方案 3:

这看起来是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

解决方案 4:

我长期使用并欣赏这个问题,以及@cs95的回答,它非常详尽并处理了所有情况。与@ra的回答类似,我也想找到一种方法来处理包含多个级别的多个索引。

我终于找到了一种方法,可以根据给定的级别或命名索引获取任意数量的切片,这可以处理上面提出的几个问题。这里的主要改进是不必解析多个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

正如@ra指出的那样,问题在于没有命名索引。使用这里的方法有很多种方法可以满足此要求,例如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']

解决方案 5:

接受的答案非常好,但当仅在第二级进行切片时(例如问题 1b 和 2b),它提供了更简洁的解决方案。它消除了和 的.loc(axis=0)必要性。get_level_values`pd.IndexSlice`


问题 1b

如何对级别“二”上值为“t”的所有行进行切片?

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

df.loc(axis=0)[:,'t']就是您所需要的。

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

df.loc(axis=0)[:,['t', 'w']]再次满足您所有需求。

axis=0相当于axis='rows'

类似地,要对 MultiIndex 列进行切片,请使用.loc(axis=1).loc(axis='columns')

解决方案 6:

一个选项是使用pyjanitor中的select_rows:

# 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

此外,我怎样才能在输出中删除级别“一”?

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

问题 1b

如何对级别“二”上值为“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

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

使用字典:

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'),如下所示

         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”相对应的所有行?

         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

如何获取“第二”级中的值大于 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

也尝试@ra 回答:

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

解决方案 7:

使用 pandas 多索引通常非常困难,因此,我创建了一个小型辅助库pandas-indexing来简化使用它们,它包含一组选择器,可以优雅地查询多索引:

from pandas_indexing import isin

问题 1

如何选择“第一”级中包含“a”的行?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
df.loc[isin(one="a")]

此外,我怎样才能在输出中删除级别“一”?

     col
two     
t      0
u      1
v      2
w      3

那就放弃吧。

df.loc[isin(one="a")].droplevel("one")

问题 1b

如何对级别“二”上值为“t”的所有行进行切片?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12
df.loc[isin(two="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[isin(one=["b", "d"])]

问题 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
df.loc[isin(two=["t", "w"])] 

问题 3

如何从 中检索横截面,即具有特定索引值的单行df?具体来说,如何检索 的横截面('c', 'u'),如下所示

         col
one two     
c   u      9
df.loc[isin(one="c", two="u")]

问题 4

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

         col
one two     
c   u      9
a   w      3

由于isin假设不同级别之间存在和,不同值之间存在,因此直观的解决方案为:

df.loc[isin(one=["c", "a"], two=["u", "w"])]

也会选择("c", "w")您可能不想要的内容,但您可以轻松地组合选择器:

df.loc[isin(one="c", two="u") | isin(one="a", two="w")]

或者如果你有一个列表,可以使用semijoin

from pandas_indexing import semijoin
semijoin(df, pd.MultiIndex.from_tuples([("c", "u"), ("a", "w")], names=["one", "two"]))

问题 5

我如何检索与“第一”级中的“a”或“第二”级中的“t”相对应的所有行?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12
df.loc[isin(one="a") | isin(two="t")]

问题 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.loc[isin(one=["a", "b"], two=["u", "v"]) | isin(one="d", two="w")]

问题 7

如何获取“第二”级中的值大于 5 的所有行?

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

从版本0.2.6开始:

df2.loc[isin(two=lambda s: s > 5)]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用