python pandas 过滤器函数正则表达式在 MultiIndex 数据帧上的行为

tag这是一个带有索引和 的MultiIndex 数据透视表uom。tag我的目标是使用正则表达式和过滤函数按索引过滤行。例如:


df.filter(regex="^Assets$", axis="index")

理想情况下会过滤掉该行:


fy                                                              2018          2019                                      tag                                                uom                                                                  Assets                                             USD  3.753190e+11  3.385160e+11  


但是,当我这样做时,它会输出一个空数据框:


Empty DataFrame                                                                                                         Columns: [2018, 2019]                                                                                                   Index: []


我能够通过使用来规避这个问题:


df.index.get_level_values("tag").str.contains("^Assets$")

或者作为一个函数


search = lambda df, regex, index_name: df.loc[df.index.get_level_values(index_name).str.contains(regex)]

但这对我来说不太令人满意。我是否遗漏了有关 pandas 过滤器功能及其正则表达式输入如何工作的信息?它没有按预期运行,我的猜测是因为我有 2 个索引:tag因此当我用作我的正则表达式时uom,正则表达式在索引中失败。uom"^Assets$""^Assets$|USD"这是通过使用返回整个数据帧的正则表达式来支持的,因为所有行都有uom=USD,并且它表明过滤器函数将两个索引都考虑在内。如果是这种情况,那么我如何有选择地tag为 MultiIndex 数据帧上的过滤器函数选择 index= ?


呼如林
浏览 202回答 3
3回答

白衣非少年

过滤器函数的正则表达式部分的实现很短,很容易适应多索引场景,在这种情况下您仍然希望只使用多索引的正则表达式 1 部分。我知道这不是对您所问内容的直接回答,因为您是对的,因为实现的过滤器功能不处理多索引。我在这里遇到了同样的问题,并认为发布我使用过的代码(改编自 pandas 原始代码)可能对其他人来说是一个有用的答案:import regex as redef filter_multi(df, index_level_name, regex, axis=0):    def f(x):        return matcher.search(str(x)) is not None    matcher = re.compile(regex)    values = df.axes[axis].get_level_values(index_level_name).map(f)    return df.loc(axis=axis)[values]使用附录中的代码:print(df)print(filter_multi(df, index_level_name='tag', regex='^Assets$', axis=0))print(filter_multi(df, index_level_name='fy', regex='^2019$', axis=1))

炎炎设计

另一种选择是首先uom从您的索引中删除,应用filter(然后将其应用于唯一的索引tag)并添加uom回您的索引,如df.reset_index('uom').filter(regex="^Assets$", axis=0).set_index('uom', append=True)

守候你守候我

如果你想从多索引的第一部分过滤一个唯一值,你可以使用loc:df.loc[['Assets']]这使:fy                  2018          2019 tag    uom                             Assets USD  3.753190e+11  3.385160e+11如果对于你的实际问题,必须使用过滤器,你应该重置索引未使用的部分并在过滤后将其设置回去:df.reset_index(level='uom').filter(regex='^Assets$', axis=0).set_index('uom', append=True)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python