给定一个具有 3 个级别的多索引的数据框:
import pandas as pd
df = pd.concat({'a': pd.Series([1,2,3,1]),
'b': pd.Series([5,4,3,5]),
'c': pd.Series(range(9,13)),
'd': pd.Series(range(13,17))}, axis=1).set_index(['a', 'b', 'c'])
>>> d
a b c
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
我想将 loc 与前 2 个级别的索引列表一起使用:
idx = pd.MultiIndex.from_arrays([[1, 2], [5, 4]], names=('a', 'b'))
>>> MultiIndex([(1, 5),
(2, 6)],
names=['a', 'b'])
我尝试将 .loc 与单独的索引一起使用:
df.loc[idx[0]]
>>> d
c
9 13
12 16
df.loc[idx[1]]
>>> d
c
10 14
我期望
df.loc[idx]
返回与相同的结果
pd.concat([df.loc[i] for i in idx])
>>> d
c
9 13
12 16
10 14
但是我
df.loc[idx]
回来了
ValueError: operands could not be broadcast together with shapes (2,2) (3,) (2,2)
有没有比
pd.concat([df.loc[i] for i in idx])
更干净的东西来获得预期的结果?
要使用
loc
和多索引数据帧前 2 个级别的索引列表来实现所需的结果,您可以使用 pd.IndexSlice
。这是一个例子:
import pandas as pd
df = pd.concat({'a': pd.Series([1, 2, 3, 1]),
'b': pd.Series([5, 4, 3, 5]),
'c': pd.Series(range(9, 13)),
'd': pd.Series(range(13, 17))}, axis=1).set_index(['a', 'b', 'c'])
idx = pd.MultiIndex.from_arrays([[1, 2], [5, 4]], names=('a', 'b'))
# Use pd.IndexSlice to slice the first two levels of the MultiIndex
idx_slice = pd.IndexSlice[:, :]
# Use loc with the sliced MultiIndex
result = df.loc[idx_slice, :].loc[idx, :]
print(result)