我有一个带有 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
有什么建议可以实现吗?
编辑 在我的用例中,标签是用笛卡尔积构造的,因此会有 (lev0、lev1、lev2) 的所有组合。 但情况是 lev0 可以取 2 个值 {A, B},而 lev1 可以取 3 个值 {a, b, c}
最佳答案
我觉得用这种方式比较安全。
dfmi.where(a_mask.loc[:,dfmi.columns.droplevel(0)].values,0)
Out[191]:
lvl0 A B
lvl1 a b a b
lvl2 bar foo bar foo bar foo bar foo
A0 0 0 0 2 0 0 0 6
A1 9 8 11 0 13 12 15 0
A2 0 16 19 18 0 20 23 22
A3 25 0 0 0 29 0 0 0
关于python - Pandas :将掩码应用于多索引数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47516935/