从没有循环的数据帧中删除行列表

2024-06-23 19:34:35 发布

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

如果不求助于for循环,就无法从大于3级的数据帧中删除多级行列表

当显式定义索引中的所有值时,这可以很好地工作,如下所示: Pandas Multiindex dataframe remove rows

例如

mask = dfmi.index.isin(( ('A0','B0', 'C0'), ('A2','B3', 'C4') ))
dfmi.loc[~mask,:]

然而,当一个人想要接受所有可能的第三层次时:

dfmi.index.isin(( ('A0','B0', slice(None)), ('A2','B3', slice(None)) ))

结果TypeError:unhable type:'slice'

目前,我正在通过以下代码实现这一点:

import numpy as np
import pandas as pd
def mklbl(prefix, n):
     return ["%s%s" % (prefix, i) for i in range(n)]

miindex = pd.MultiIndex.from_product([mklbl('A', 4),
                                   mklbl('B', 4),
                                   mklbl('C', 10)])

dfmi = pd.DataFrame(np.arange(len(miindex) * 2)
               .reshape((len(miindex), 2)),
                index=miindex).sort_index().sort_index(axis=1)

As = ['A0', 'A2']
Bs = ['B1', 'B3']

for a,b in zip(As, Bs):
    dfmi_drop_idx = dfmi.loc[(a, b, slice(None)), :].index
    dfmi.drop(dfmi_drop_idx, inplace=True, errors='ignore')

Tags: nonea2forindexslicemaskb0a0
2条回答

drop在一个元组列表上应该做这个技巧

dfmi.drop([*zip(As, Bs)])

为了验证,这是代码的修改版本。我们将输出与asser等式进行比较

from functools import reduce
didx = reduce(
    pd.MultiIndex.union,
    [dfmi.loc[pd.IndexSlice[a, b, :], :].index
     for a, b in zip(As, Bs)]
)

assert dfmi.drop(didx).equals(dfmi.drop([*zip(As, Bs)]))

创建MultiIndex索引,然后删除它

dfmi.drop(pd.MultiIndex.from_arrays([As,Bs]))

相关问题 更多 >

    热门问题