Pandas使用.loc对MultiIndex的一部分进行MultiIndex筛选

e0bqpujr  于 2022-12-09  发布在  其他
关注(0)|答案(4)|浏览(145)

我想只使用3级MultiIndex中的2级来筛选DataFrame。有没有办法用.loc来实现这一点?
我设法做到这一点的唯一方法是:

df=pd.DataFrame(index=pd.MultiIndex.from_tuples([(1,'a','x')
,(1,'a','y')
,(1,'b','z')
,(1,'b','x')
,(2,'c','y')
,(2,'c','z')
,(2,'a','x')
,(2,'a','y')
,(3,'b','z')
,(3,'b','x')
,(3,'c','y')
,(3,'c','z')]), 
data=[20,26,43,20,65,40,87,41,84,50,5,54])

f=[(2, 'a'), (3, 'b'), (3, 'c')]

df=df.reset_index(level=2).loc[f].reset_index().set_index(['level_0','level_1','level_2'])

结果df为:
| | | | 第0页|
| - -|- -|- -|- -|
| 级别_0|级别_1|级别_2||
| 2个|一种|X射线|八十七|
| | | Y形|四十一|
| 三个|B| Z形|八十四|
| | | X射线|五十个|
| | C语言|Z形|五个|
| | | X射线|五十四|
我想要的是能够执行类似df.loc[(f,slice(None))]的操作,以使代码变得简单一些

ergxz8rk

ergxz8rk1#

我认为f是不合适例子,因为a和b在2和3中不重叠
让我们从1中取a,从3中只取B(因为1也有b)

idx = [(1, 'a'), (3, 'b')]
df[df.index.droplevel(2).isin(idx)]

实验结果:

0
1   a   x   20
        y   26
3   b   z   84
        x   50
lf3rwulv

lf3rwulv2#

IIUC您仍然可以实现这一点,只需在loc中正确构建元组。

df.loc[([2, 3], ["a", "b"], ), :]

输出量:

0
2 a x  87
    y  41
3 b z  84
    x  50
ds97pgxw

ds97pgxw3#

另一种方法是使用get_locs,它的输出可以用来使用iloc定位。基本上,get_locs根据传递的索引返回一个整数序列。

df.iloc[np.ravel([df.index.get_locs(t) for t in f])]

输出量:

0
2 a x  87
    y  41
3 b z  84
    x  50
2sbarzqh

2sbarzqh4#

一个选项是select_rows from pyjanitor-您的数据可能需要排序以避免出现性能警告:

# pip install pyjanitor
import pandas as pd
import janitor

df.sort_index().select_rows(f)
        0
2 a x  87
    y  41
3 b x  50
    z  84
  c y   5
    z  54

相关问题