You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Pandas多级索引下.loc方法的使用疑问及预期结果实现需求

嘿,我来帮你把这个MultiIndex下的.loc用法问题理清楚~

首先先还原你的场景,执行以下代码:

import pandas as pd
df=pd.DataFrame({'a':[1,2,3,4,5,6,7,8],'b':['g1','g1','g1','g1','g2','g2','g2','g2'],'c':['v1','v2','v1','v2','v1','v2','v1','v2']})
df.set_index(['b','c'], inplace=True)

生成的DataFrame如下:

a
b   c   
g1  v1  1
    v2  2
    v1  3
    v2  4
g2  v1  5
    v2  6
    v1  7
    v2  8

你的疑问拆解

1. 为什么df.loc['g1','v1']会返回两行数据?

你之前的理解是.loc[row,col]的第二个参数是列标签,但这里的核心是:你给DataFrame设置了多层行索引(MultiIndex)bc都是行索引的层级,而不是“行+列”的对应关系。

当你写df.loc['g1','v1']时,pandas会自动把这两个参数对应到行索引的第一层(b)和第二层(c),相当于筛选「行索引第一层为g1且第二层为v1」的所有行,所以会返回这两行结果:

a
b   c   
g1  v1  1
    v1  3

2. 为什么df.loc[:,'v1']无法得到预期的所有v1行?

这是因为.loc[:, 'v1']里的第二个参数是在指定列标签,而你的DataFrame里只有一列a,根本没有名为v1的列,所以这样写要么报错,要么返回空结果,自然没法筛选到行索引里的v1

如何获取你想要的结果?

要筛选所有行索引第二层为v1的行,这里有3种常用且清晰的方法:

方法1:用切片+元组指定MultiIndex

直接通过元组来匹配多层索引的层级,slice(None)表示匹配第一层索引的所有值:

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

方法2:用IndexSlice(可读性更强)

先导入IndexSlice,可以更直观地写出筛选逻辑:

from pandas import IndexSlice
df.loc[IndexSlice[:, 'v1'], :]

方法3:用xs方法(专门针对MultiIndex的工具)

xs是pandas专门为多层索引设计的筛选方法,level参数指定要筛选的索引层级(可以写层级名称'c'或者索引位置1),drop_level=False用来保留原有的多层索引结构:

df.xs('v1', level='c', drop_level=False)

以上三种方法都能得到你预期的结果:

a
b   c   
g1  v1  1
    v1  3
g2  v1  5
    v1  7

内容的提问来源于stack exchange,提问作者HappyPy

火山引擎 最新活动