Python 筛选多索引数据帧中的多个项

Python 筛选多索引数据帧中的多个项,python,filter,pandas,indexing,Python,Filter,Pandas,Indexing,我有下表: 注意:NSRCODE和PBL_AWI都是索引 注:面积百分比栏将填写,但尚未填写 NSRCODE PBL_AWI Area % Of Area CM BONS 44705.492941 BTNN 253854.591990 FONG 41625.590370 FONS 16814.159

我有下表:

注意:NSRCODE和PBL_AWI都是索引

注:面积百分比栏将填写,但尚未填写

NSRCODE  PBL_AWI          Area           % Of Area
CM       BONS             44705.492941
         BTNN            253854.591990
         FONG             41625.590370
         FONS             16814.159680
         Lake             57124.819333
         River             1603.906642
         SONS            583958.444751
         STNN             45603.837177
         clearcut        106139.013930
         disturbed       127719.865675
         lowland         118795.578059
         upland         2701289.270193
LBH      BFNN            289207.169650
         BONS           9140084.716743
         BTNI             33713.160390
         BTNN          19748004.789040
         FONG           1687122.469691
         FONS           5169959.591270
         FTNI            317251.976160
         FTNN           6536472.869395
         Lake            258046.508310
         River            44262.807900
         SONS           4379097.677405
         burn regen      744773.210860
         clearcut         54066.756790
         disturbed       597561.471686
         lowland       12591619.141842
         upland        23843453.638117
如何筛选出“PBL_AWI”索引中的项目?
例如,我想保留['Lake'、'River'、'Upland']

您可以
结合布尔切片来获取\u level\u值

In [50]:

print df[np.in1d(df.index.get_level_values(1), ['Lake', 'River', 'Upland'])]
                          Area
NSRCODE PBL_AWI               
CM      Lake      57124.819333
        River      1603.906642
LBH     Lake     258046.508310
        River     44262.807900
同样的想法可以用许多不同的方式表达,例如
df[df.index.get_level_values('PBL\u AWI')。isin(['Lake'、'River'、'Upland'])]

请注意,您的数据中有
'upland'
,而不是
'upland'
(来自):

。。。用作

df.filter_by({'PBL_AWI' : ['Lake', 'River', 'Upland']})
(未测试面板和更高维度的元素,但我确实希望它能工作)

另一种(可能更干净)方法可能是:

print(df[df.index.isin(['Lake', 'River', 'Upland'], level=1)])

参数
level
指定索引编号(以0开头)或索引名称(此处:
level='PBL\u AWI'

这是对所问问题的一个细微变化的回答,可能会为其他人节省一点时间。如果要查找与不知道其确切值的标签匹配的通配符类型,可以使用以下方法:

q_labels = [ label for label in df.index.levels[1] if label.startswith('Q') ]
new_df = df[ df.index.isin(q_labels, level=1) ]
df.过滤器(regex=…,axis=…)更简洁,因为它同时作用于index=0和column=1轴。您不需要担心级别,而且可以懒得使用正则表达式。索引过滤器的完整示例:

df.filter(regex='Lake|River|Upland',axis=0)

如果对其进行转置,并尝试对列进行过滤(默认情况下,轴=1),它也可以工作:

df.T.filter(regex='Lake|River|Upland')

现在,使用regex,您还可以轻松解决Upland的大小写问题:

upland = re.compile('Upland', re.IGNORECASE)
df.filter(regex=upland ,axis=0)

这是读取上述输入表的命令:


df=pd.read\u csv(io.StringIO(输入表格),sep=“\s{2,}”)。设置索引(['NSRCODE',PBL\u AWI'])

如果您的表名是df,那么['Lake'、'River'、'Upland']中的df[df['PBL\u AWI']或df[df['PBL\u AWI']='Lake'或df['PBL\u AWI']='River或df['PBL\u AWI']中的df['PBL\u AWI']就应该这样做。过滤是非常基本的东西,你应该看到@Inox,我意识到过滤是我以前在单索引数据帧上做过的非常基本的东西。然而,在尝试上面的方法时,多索引数据帧会产生“keyrerror:u'no item named PBL_AWI'”。尽管@CTZhu的答案正确,但请注意,您可以先执行
df=df.reset_index()
来使用类似@Inox的解决方案。如果找不到更好的解决方案,我通常会使用多索引。但我发现通常有一个更好的解决方案,只是不太容易发现。如果您有兴趣了解更多关于切片和过滤多索引数据帧的信息,请参阅我的帖子:。谢谢虽然这段代码可以解决这个问题,但如何以及为什么解决这个问题将真正有助于提高您的帖子质量,并可能导致更多的投票。请记住,你是在将来回答读者的问题,而不仅仅是现在提问的人。请您在回答中添加解释,并说明适用的限制和假设。在这种情况下,对这些问题已经有了丰富的讨论,如果受访者不想在教科书上写一章,我仍然认为这个答案很有用。我发现第二个解决方案对类似问题很有用,选择多索引值大于给定值的行:
df[df.index.get_level_values('level_name')>1]
。第二个解决方案应该是答案,更清晰,不需要np。不过,看看什么更快会很有趣。np已经是熊猫的一种依赖,所以几乎不成问题。
upland = re.compile('Upland', re.IGNORECASE)
df.filter(regex=upland ,axis=0)