如何基于条件删除MultiIndex DataFrame各level 0分组下的level 1索引行
实现方案
前置说明
假设你的MultiIndex结构DataFrame命名为df,level 0索引为Date、level 1索引为Ticker,且已按Date分组、Volume升序排序。
方案1:已提前排序场景,删每个分组最低N个标的(示例中删2个)
因为已经完成组内升序排序,直接通过组内序号过滤即可,运算效率最高,适合大规模数据集:
# 给每个Date分组内的行生成从0开始的递增序号 df['group_seq'] = df.groupby(level='Date').cumcount() # 过滤掉序号前2位(对应成交量最低的2个标的),删除临时列 df = df[df['group_seq'] >= 2].drop('group_seq', axis=1)
方案2:通用场景,删每个分组最低十分位标的(实际业务需求)
通过groupby.apply对每个日期分组单独计算分位数过滤,解决你之前qcut只能单日期生效的问题:
def filter_low_vol(group): # 计算当前分组成交量的10%分位阈值 vol_threshold = group['Volume'].quantile(0.1) # 仅保留成交量大于阈值的标的 return group[group['Volume'] > vol_threshold] # group_keys=False避免生成额外的分组索引层级 df = df.groupby(level='Date', group_keys=False).apply(filter_low_vol)
方案3:未提前排序场景,删每个分组最低N个标的
修正你之前nsmallest报错的问题,处理返回的索引层级即可:
# 提取每个Date分组下成交量最低的2个标的的索引 drop_idx = df.groupby(level='Date')['Volume'].nsmallest(2).index.droplevel(0) # 直接删除对应行 df = df.drop(drop_idx)
内容的提问来源于stack exchange,提问作者Ineedhelp
相关产品推荐
相关产品推荐

