有没有更好的方法从多索引中选择多个值 而不是
df.loc[(slice(None), ['one','seven'], slice(None), ['a','d','l'])]
类似:
df.loc[ {level_1: ['one','two'], level_3: ['a','d','l'] } ]
我试过 df.xs
但这只允许每一级有一个键。
答案 0 :(得分:0)
示例数据
import pandas as pd
index = pd.MultiIndex.from_product([['A', 'B'], ['a', 'b'], [1, 2, 3]],
names=['foo', 'bar', 'baz'])
df = pd.DataFrame({'data': range(12)}, index=index)
pd.IndexSlice
它与您的原始选择没有任何不同,但语法稍微紧凑一些,因为您可以使用 :
而不是 slice(None)
idx = pd.IndexSlice
df.loc[idx['A', :, [1,3]]]
# data
#foo bar baz
#A a 1 0
# 3 2
# b 1 3
# 3 5
该函数本身相当冗长,但在编写完成后,您几乎可以忽略它并处理自文档签名。
您提供一个字典,其中键是级别名称(或对应于该级别编号的整数),值是您要为该级别包含的标签。我添加了一个检查,您可以为多个标签指定一个可迭代对象,例如列表/数组/元组,并为您只需要一个标签的级别指定一个值。
import numpy as np
def get_slice(df, slice_dict):
m = np.logical_and.reduce(
[df.index.get_level_values(level).isin(v) if (hasattr(v, '__iter__') and not isinstance(v, str))
else df.index.get_level_values(level) == v
for level,v in slice_dict.items()])
return df.loc[m]
get_slice(df, {'foo': 'A', 'baz': [1, 3]})
# data
#foo bar baz
#A a 1 0
# 3 2
# b 1 3
# 3 5