为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

精慕HU 2022-09-06 15:38:13
我在熊猫数据帧中有一个带有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         cRun 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.0707301   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.2262722   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
查看完整描述

2 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

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 = select

df.select(set1) # etc.

请注意,这将忽略 在 中不存在的级别:indexdf.index


# there's no level "FooBar" in df

set4 = pd.MultiIndex.from_tuples([(0, 42)], names=['Trigger', 'FooBar'])

df.select(set4) # works just fine

我还没有测试性能,如果你在一个紧密的循环中这样做,可能不会太快。


查看完整回答
反对 回复 2022-09-06
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

使用纯熊猫实现此目的的一种方法是:

df.align(setN.to_series(), axis=0, join='inner')[0]

也就是说,将“其他”索引转换为 Series,并选择在内部连接操作期间将保留的每个索引的部分。


查看完整回答
反对 回复 2022-09-06
  • 2 回答
  • 0 关注
  • 217 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号