使用部分索引元组列表对多索引数据帧进行切片的最佳方法是啥?

Posted

技术标签:

【中文标题】使用部分索引元组列表对多索引数据帧进行切片的最佳方法是啥?【英文标题】:What is the best way to slice a multiindex dataframe using a list of partial index tuples?使用部分索引元组列表对多索引数据帧进行切片的最佳方法是什么? 【发布时间】:2019-12-28 07:41:25 【问题描述】:

我想使用部分匹配的索引或元组列表对数据框进行切片。

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

...但是当我的查询索引很大时,这非常笨拙。有没有更好的办法?

【问题讨论】:

【参考方案1】:

您可以尝试在面具上使用index.droplevelisin.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

【讨论】:

【参考方案2】:

使用来自pandaspd.IndexSlice

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 中以标记它是一个切片。最后,最后一个: 告诉我们我们想要所有的列。

【讨论】:

【参考方案3】:

这是一种方法

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

【讨论】:

以上是关于使用部分索引元组列表对多索引数据帧进行切片的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 pandas 多索引数据帧切片看起来不一致?

将熊猫多索引切片彼此分开

使用句点选择/切片多索引数据帧时间序列会导致错误?

对唯一顺序索引的多索引熊猫数据框进行切片和赋值

将多索引数据帧的索引值提取为python中的简单列表

将值从一个数据帧切片复制到另一个:使用“IndexSlice”的多索引熊猫数据帧的切片是不是总是一致地排序?