【发布时间】:2014-04-26 14:46:59
【问题描述】:
我在 pandas 中有一个多索引数据框,索引中有 4 列,还有一些数据列。下面是一个例子:
import pandas as pd
import numpy as np
cnames = ['K1', 'K2', 'K3', 'K4', 'D1', 'D2']
rdata = pd.DataFrame(np.random.randint(1, 3, size=(8, len(cnames))), columns=cnames)
rdata.set_index(cnames[:4], inplace=True)
rdata.sortlevel(inplace=True)
print(rdata)
D1 D2
K1 K2 K3 K4
1 1 1 1 1 2
1 1 2
2 1 2 1
2 1 2 2 1
2 1 2 1
2 1 2 2 2 1
2 1 2 1 1
2 1 1
[8 rows x 2 columns]
我想要做的是选择在 K3 级别恰好有 2 个值的行。不是 2 行,而是两个不同的值。我已经找到了如何为我想要的东西生成一种掩码:
filterFunc = lambda x: len(set(x.index.get_level_values('K3'))) == 2
mask = rdata.groupby(level=cnames[:2]).apply(filterFunc)
print(mask)
K1 K2
1 1 True
2 True
2 1 False
2 False
dtype: bool
而且我希望由于rdata.loc[1, 2] 允许您仅匹配索引的一部分,因此可以使用像这样的布尔向量来做同样的事情。不幸的是,rdata.loc[mask] 以 IndexingError: Unalignable boolean Series key provided 失败。
This question 看起来很相似,但那里给出的答案除了顶级索引外,其他任何东西都不起作用,因为 index.get_level_values 仅适用于单个级别,而不适用于多个级别。
按照here的建议,我设法完成了我想要的
rdata[[mask.loc[k1, k2] for k1, k2, k3, k4 in rdata.index]]
但是,使用len(set(index.get_level_values(...))) 获取不同值的计数以及之后通过迭代每一行来构建布尔向量感觉更像是我在与框架作斗争以实现在多索引设置中看似简单的任务。有没有更好的解决方案?
这是使用 pandas 0.13.1。
【问题讨论】: