如何对Pandas MultiIndex DataFrame按年、州删除age列最低5个值
Pandas多级索引分组删除指定列最小值数据的实现方案
你可以根据数据量大小选择以下两种实现方式:
方案1:简单直观的分组+排序切片(适合中小数据量)
核心逻辑是按Year和State两个索引层级分组后,每组按age升序排序,直接丢弃前5条最小的记录:
import pandas as pd # 此处df替换为你的原始DataFrame变量名 res_df = df.groupby(level=["Year", "State"], group_keys=False).apply( lambda group: group.sort_values("age", ascending=True).iloc[5:] )
如果需要兼容部分分组数据不足5条的场景,避免该分组数据被全部删除,可以修改为:
res_df = df.groupby(level=["Year", "State"], group_keys=False).apply( lambda group: group.sort_values("age", ascending=True).iloc[5:] if len(group) > 5 else group )
方案2:高性能rank函数实现(适合百万级以上大数据量)
避免apply的循环开销,用分组排名的方式直接过滤记录:
# 按分组对age做升序排名,method=first保证重复值也能生成唯一连续排名,确保刚好删除5条 df["age_rank"] = df.groupby(level=["Year", "State"])["age"].rank(method="first", ascending=True) # 保留排名大于5的记录,删除临时排名列 res_df = df[df["age_rank"] > 5].drop(columns=["age_rank"])
如果要兼容分组数据不足5条保留全量的需求,可以调整过滤条件:
# 先统计每个分组的大小 group_size = df.groupby(level=["Year", "State"]).size().rename("group_size") df = df.join(group_size, on=["Year", "State"]) df["age_rank"] = df.groupby(level=["Year", "State"])["age"].rank(method="first", ascending=True) # 分组大小不足5的全留,否则只留排名大于5的 res_df = df[(df["group_size"] <=5) | (df["age_rank"] >5)].drop(columns=["age_rank", "group_size"])
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

