我有一个带有 MultiIndex 列的 pandas 数据框,有 3 个级别:
import itertools
import numpy as np
def mklbl(prefix, n):
return ["%s%s" % (prefix, i) for i in range(n)]
miindex = pd.MultiIndex.from_product([mklbl('A', 4)])
micolumns = pd.MultiIndex.from_tuples(list(itertools.product(['A', 'B'], ['a', 'b', 'c'], ['foo', 'bar'])),
names=['lvl0', 'lvl1', 'lvl2'])
dfmi = pd.DataFrame(np.arange(len(miindex) * len(micolumns)).reshape((len(miindex), len(micolumns))),
index=miindex,
columns=micolumns).sort_index().sort_index(axis=1)
lvl0 A B
lvl1 a b c a b c
lvl2 bar foo bar foo bar foo bar foo bar foo bar foo
A0 1 0 3 2 5 4 7 6 9 8 11 10
A1 13 12 15 14 17 16 19 18 21 20 23 22
A2 25 24 27 26 29 28 31 30 33 32 35 34
A3 37 36 39 38 41 40 43 42 45 44 47 46
我想基于另一个数据帧来屏蔽这个数据帧,该数据帧具有索引的最后两个级别:
cols = micolumns.droplevel(0).unique()
a_mask = pd.DataFrame(np.random.randn(len(dfmi.index), len(cols)), index=dfmi.index, columns=cols)
a_mask = (np.sign(a_mask) > 0).astype(bool)
a b c
foo bar foo bar foo bar
A0 False False False True True False
A1 True False True False True True
A2 True True True True False False
A3 True False False True True False
我想做的是根据以下内容屏蔽原始数据框a_mask
。
假设我想将原始条目设置为零,当a_mask
是真的。
我尝试使用pd.IndexSlice
,但它默默地失败了(即我可以运行以下代码,但没有效果:
dfmi.loc[:, pd.IndexSlice[:, a_mask]] = 0 #dfmi is unchanged
有什么建议如何实现这一目标吗?
Edit在我的用例中,标签是用笛卡尔积构造的,因此将存在 (lev0、lev1、lev2) 的所有组合。
但情况是 lev0 可以假设 2 个值 {A, B},而 lev1 可以假设 3 个值 {a, b, c}