提问人:byrey3 提问时间:7/3/2023 最后编辑:byrey3 更新时间:7/3/2023 访问量:45
在 Pandas Multiindex 中,如何在不知道关卡位置的情况下进行索引切片?
In Pandas Multiindex, how do you do an indexslice without knowing the position of the level?
问:
我有一个处理 pandas 数据帧的程序,使用 2 个级别(日期和数据)的多索引,例如:
Date_Time Data
date1 a
b
c
date2 a
b
c
date3 a
b
c
...
因此,当必须使用/修改 df 的内容时,所有函数都使用 pandas IndexSlice,例如:
df.loc[pd.IndexSlice[:,'a'],:]
这很好用,易于阅读,简短高效,并且使许多单行功能成为可能。
但是,我目前必须根据某些属性来区分数据,以便在进行重采样时不会使它们合并,并且我通过在必要时向索引添加第三级来做到这一点:
Date_Time Property Data
date1 1 a
1 b
1 c
date2 2 a
2 b
2 c
date3 1 a
1 b
1 c
...
目标是能够随着时间的推移进行重新采样的分组,并最终得到这个多索引:
Date_Time Property Data
Period1 1 a
1 b
1 c
2 a
2 b
2 c
Period2 1 a
1 b
1 c
...
所以,问题是不再有效,我必须将其更改为df.loc[pd.IndexSlice[:,'a'],:]
df.loc[pd.IndexSlice[:,:,'a'],:]
但这意味着每次我将该数据帧与额外列一起使用时,都要更改代码本身。
有没有办法以灵活的方式定义切片??
我想使用变量来定义切片,就像在列表推导中一样,这样就可以防止将来对多索引级别的长度和顺序进行更多更改。但据我所知,这是不可能的,那我该怎么办??
我可以在每个函数的开头使用 try-except 块来定义切片,在已经确保级别和level_value存在的块内;或将属性级别向右移动,以便我仍然可以使用(但将来我可能会再次遇到这个问题)pd.IndexSlice[:,'a']
编辑:下面是一些代码,用于生成使用这种索引的数据帧:
iter1=[["03/07/2023 07:40:00", "03/07/2023 07:50:00"], ["S=0.1"],["Probe1","Probe2","Probe3"]]
iter2=[["03/07/2023 07:45:00", "03/07/2023 07:55:00"], ["S=0.2"],["Probe1","Probe2","Probe3"]]
idx1=pd.MultiIndex.from_product(iter1, names=["Date_Time", "Property",'Data'])
idx2=pd.MultiIndex.from_product(iter2, names=["Date_Time", "Property",'Data'])
df_aux1=pd.DataFrame(np.random.randn(6, 3), index=idx1, columns=['X','Y','Error'])
df_aux2=pd.DataFrame(np.random.randn(6, 3), index=idx2, columns=['X','Y','Error'])
df=pd.concat([df_aux1,df_aux2]).sort_index(level='Date_Time')
答:
1赞
mozway
7/3/2023
#1
确切的数据和逻辑尚不清楚,但由于您已经命名了级别,因此可以使用Index.get_level_values
和布尔索引:
df.loc[df.index.get_level_values('Data') == 'a']
或按位置:
df.loc[df.index.get_level_values(-1) == 'a']
评论
1赞
byrey3
7/4/2023
谢谢,它如我所愿。但是,我遇到了一次过滤多个级别值的问题,我使用它解决了这个问题,因此如果我想要而不是“a”,它也可以工作,我不知道这是否是效率方面的最佳选择,但如果其他人遇到同样的问题,那应该会有所帮助df.index.get_level_values('Data').isin('a')
['a','c']
评论
df