我有一个df
和一个多级MultiIndex
。早期我需要标记某些行来保存;在随后的分类和处理中,这些行将总是被保留。
我有工作代码,但它不是很有吸引力,我想知道是否有一个更漂亮/更有效的方法来做到这一点。
给定一个df
,其中MultiIndex
的级别为3+,列数为任意数量,我运行以下代码来检查MultiIndex
的前2个级别中是否存在重复项,并将第一个出现的项标记为keeper:
df['keeper'] = df.index.isin(df.assign(check=df.index.get_level_values(0), check2=df.index.get_level_values(1)).drop_duplicates(subset=['check', 'check2']).index)
下面是一个玩具df
,其结果为keeper
列:
0 keeper
lev0 lev1 lev2
1 1 1 0.696469 True
2 NaN False
2 3 0.719469 True
2 0.980764 False
3 1 NaN True
我尝试了reset_index
,但最后我需要MultiIndex保持不变,并且将这些级别移动到列中,然后再次重新创建非常大的MultiIndex,这似乎比我的效率更低。
2条答案
按热度按时间lf5gs5x21#
这应该也可以。它的灵感来自于mozway在链接上的回答。
OP编辑:
我在一个10级MultiIndex的1000x1000 df上对各种解决方案(以及我的原始代码)进行了计时,这个解决方案(使用
droplevel
和names.difference
)是明显的赢家,超过了一个数量级。从最快到最慢:8aqjt8rx2#
感谢@rhug123和the answer he posted,我改进了我的原始代码,使用
duplicated
代替drop_duplicates
,否定了对.index.isin
的需求。我选择不使用to_frame
,因为我的MultiIndex是10级深,复制所有的级别只是为了使用2似乎效率低下。这两种解决方案都只提取所需的索引级别。3种不同的选择,从最慢到最快:
在
reset_index
之后,需要to_numpy
,因为索引不再与原始索引匹配。第三种解决方案首先删除所有使用df[[]]
的列,因此不需要subset
。