无法弄清楚如何在不诉诸 for 循环的情况下从大于 3 级的 pandas 数据帧中删除多级行列表。
当显式定义索引中的所有值时,这工作正常,由以下人员回答:熊猫多索引数据帧删除行
例如
mask = dfmi.index.isin(( ('A0','B0', 'C0'), ('A2','B3', 'C4') ))
dfmi.loc[~mask,:]
但是,当一个人想要接受所有可能的第三层次时:
dfmi.index.isin(( ('A0','B0', slice(None)), ('A2','B3', slice(None)) ))
结果类型错误:不可哈希类型:"切片">
目前,我正在使用以下代码实现此目的:
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')
创建MultiIndex
索引,然后将其删除
dfmi.drop(pd.MultiIndex.from_arrays([As,Bs]))
元 组列表上的
组列表上的drop
应该可以解决问题
dfmi.drop([*zip(As, Bs)])
为了验证,这是代码的修改版本。 我们将比较输出以断言相等性。
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)]))