Pandas:对多索引数据帧应用掩码

2024-06-23 19:54:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含多索引列的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

我想根据另一个dataframe来屏蔽这个dataframe,它有索引的最后两个级别:

^{pr2}$

我想做的是根据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}


Tags: importprefixindexlenfoonpbarmask
3条回答

使用底层数组数据进行现场编辑以提高内存效率(不创建任何其他数据帧)

d = len(dfmi.columns.levels[0])
n = dfmi.shape[1]//d
for i in range(0,d*n,n):
    dfmi.values[:,i:i+n][a_mask] = 0

样本运行-

^{pr2}$

我将按如下方式进行:

mask = pd.concat({k: a_mask for k in dfmi.columns.levels[0]}, axis=1)
dfmi.where(~mask, 0)

我认为用这种方法更安全。在

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

相关问题 更多 >

    热门问题