Pandas 1.0.1-如何使用包含切片器的列表对具有多索引的数据帧进行索引

Pandas 1.0.1-如何使用包含切片器的列表对具有多索引的数据帧进行索引,pandas,indexing,Pandas,Indexing,作为示例数据集- In [12]: import numpy as np; import pandas as pd In [24]: data_raw = pd.DataFrame([ ...: ...: {'frame': 1, 'face': np.NaN, 'lmark': np.NaN, 'x': np.NaN, 'y': np.NaN}, ...

作为示例数据集-

In [12]: import numpy as np; import pandas as pd                                                     

In [24]: data_raw = pd.DataFrame([  
    ...:      ...: {'frame': 1, 'face': np.NaN, 'lmark': np.NaN, 'x': np.NaN, 'y': np.NaN},  
    ...:      ...: {'frame': 197, 'face': 0, 'lmark': 1, 'x': 969, 'y': 737},  
    ...:      ...: {'frame': 197, 'face': 0, 'lmark': 2, 'x': 969, 'y': 740},  
    ...:      ...: {'frame': 197, 'face': 0, 'lmark': 3, 'x': 970, 'y': 744},  
    ...:      ...: {'frame': 197, 'face': 0, 'lmark': 4, 'x': 972, 'y': 748},  
    ...:      ...: {'frame': 197, 'face': 0, 'lmark': 5, 'x': 973, 'y': 752},  
    ...:      ...: {'frame': 300, 'face': 0, 'lmark': 1, 'x': 745, 'y': 367},   
    ...:      ...: {'frame': 300, 'face': 0, 'lmark': 2, 'x': 753, 'y': 411},   
    ...:      ...: {'frame': 300, 'face': 0, 'lmark': 3, 'x': 759, 'y': 455},  
    ...:      ...: {'frame': 301, 'face': 0, 'lmark': 1, 'x': 741, 'y': 364},    
    ...:      ...: {'frame': 301, 'face': 0, 'lmark': 2, 'x': 746, 'y': 408},    
    ...:      ...: {'frame': 301, 'face': 0, 'lmark': 3, 'x': 750, 'y': 452}]).set_index(['frame', 'face', 'lmark'])                                        
在Pandas 1.0.3中,我可以使用以下代码过滤掉上面的数据帧行,其中
lmark
>3-

data_filtered = data_raw.loc[(slice(None), slice(None), [np.NaN, slice(3)]), :]
但在Pandas 1.1.0中,同样的声明在

TypeError: unhashable type: 'slice'
显然,这一变化是由政府决定的


在这种情况下,我如何过滤掉lmark>3下面的数据帧行?

注意:熊猫1.0之前的版本不太确定。如果您必须处理低于Pandas 1.0的版本,@jezrael的解决方案要稳定得多

不知道这是否符合您的用例,您只需要lmark上少于3行:


使用
indexlice
slice
选择仅在某些版本中正确工作,因此我建议使用另一种方法,按条件选择:

筛选依据:

或通过:

如果需要,选择不带
>3的所有值:

df = data_raw[~(data_raw.index.get_level_values('lmark') > 3)]
或所有小于3且缺少值的值:

i = data_raw.index.get_level_values('lmark')
df = data_raw[(i <= 3) | i.isna()]


data_raw.loc[idx[:,:,:3],:]
过滤掉行
lmark
>3和
lmark
=np.NaN。我只想过滤掉行
lmark
>3编辑代码。让我知道这是不是你的本事mind@sammywemmy-嗯,对我来说,你的代码省略了
NaN
s,因此
indexlice
也依赖于版本…@jezrael,OP使用的是1.1.0版。编辑代码以包含Nant这个答案也是正确的,但在更一般的情况下-用显式索引值替换切片器,例如
[np.nan,1,2,3,…N]
会很不方便。我更喜欢
df=data\u raw[~(data\u raw.index.get\u level\u values('lmark')>3)]
,谢谢
vals = [np.nan,1,2,3]
df = data_raw[data_raw.index.get_level_values('lmark').isin(vals)]
df = data_raw[~(data_raw.index.get_level_values('lmark') > 3)]
i = data_raw.index.get_level_values('lmark')
df = data_raw[(i <= 3) | i.isna()]
df = data_raw.groupby(level=0).head(3)
print (df)
                      x      y
frame face lmark              
1     NaN  NaN      NaN    NaN
197   0.0  1.0    969.0  737.0
           2.0    969.0  740.0
           3.0    970.0  744.0
300   0.0  1.0    745.0  367.0
           2.0    753.0  411.0
           3.0    759.0  455.0
301   0.0  1.0    741.0  364.0
           2.0    746.0  408.0
           3.0    750.0  452.0