使用来自单独部分 MultiIndex 的条目从 pandas DataFrame 中选择行的子集

我在熊猫数据帧中有一个带有MultiIndex的数据。让我们将我的 MultiIndex 的标签称为“运行”、“触发器”和“群集”。另外,我有一个预先计算的选择标准列表,我得到的是一个通过的条目列表(这些往往是稀疏的,因此列出传递的索引是最节省空间的)。选择剪切只能部分索引,例如,只能指定“运行”或(“运行”,“触发器”)对。


如何有效地应用这些切口,理想情况下,无需检查它们以找到它们的水平?


例如,请考虑以下数据:


index = pandas.MultiIndex.from_product([[0,1,2],[0,1,2],[0,1]], names=['Run','Trigger','Cluster'])

df = pandas.DataFrame(np.random.rand(len(index),3), index=index, columns=['a','b','c'])

print(df)


                            a         b         c

Run Trigger Cluster                              

0   0       0        0.789090  0.776966  0.764152

            1        0.196648  0.635954  0.479195

    1       0        0.007268  0.675339  0.966958

            1        0.055030  0.794982  0.660357

    2       0        0.987798  0.907868  0.583545

            1        0.114886  0.839434  0.070730

1   0       0        0.520827  0.626102  0.088976

            1        0.377423  0.934224  0.404226

    1       0        0.081669  0.485830  0.442296

            1        0.620439  0.537927  0.406362

    2       0        0.155784  0.243656  0.830895

            1        0.734176  0.997579  0.226272

2   0       0        0.867951  0.353823  0.541483

            1        0.615694  0.202370  0.229423

    1       0        0.912423  0.239199  0.406443

            1        0.188609  0.053396  0.222914

    2       0        0.698515  0.493518  0.201951

            1        0.415195  0.975365  0.687365

选择标准可以采取以下任何形式:


set1:

Int64Index([0], dtype='int64', name='Run')


set2:

MultiIndex([(0, 1),

            (1, 2)],

           names=['Run', 'Trigger'])

set3:

MultiIndex([(0, 0, 1),

            (1, 0, 1),

            (2, 1, 0)],

           names=['Run', 'Trigger', 'Cluster'])



pandas可以很容易地加入这些类型的混合级别索引,所以看起来这应该是一个简单的操作,但我无法弄清楚写入调用。 适用于 set3,因为索引的深度相同,但我需要一个通用的解决方案。loc


精慕HU
浏览 218回答 2
2回答

白板的微信

df.loc[set3]工作,因为具有索引的所有3个级别。您可以模拟此行为,并将缺少的级别替换为 :set3set1set2slicer(None)def select(df, index):    slicer = []    for name in df.index.names:        if name in index.names:            values = index.get_level_values(name).values        else:            values = slice(None)        slicer.append(values)    return df.loc[tuple(slicer), :]然后,您可以使用:select(df, set1)select(df, set2)select(df, set3)如果您希望它作为数据帧上的方法:pd.DataFrame.select = selectdf.select(set1) # etc.请注意,这将忽略 在 中不存在的级别:indexdf.index# there's no level "FooBar" in dfset4 = pd.MultiIndex.from_tuples([(0, 42)], names=['Trigger', 'FooBar'])df.select(set4) # works just fine我还没有测试性能,如果你在一个紧密的循环中这样做,可能不会太快。

人到中年有点甜

使用纯熊猫实现此目的的一种方法是:df.align(setN.to_series(), axis=0, join='inner')[0]也就是说,将“其他”索引转换为 Series,并选择在内部连接操作期间将保留的每个索引的部分。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python