You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何删除双层索引DataFrame中每个外层索引对应的首行?

如何删除多层索引DataFrame中每个外层索引对应的首行

我来帮你解决这个多层索引DataFrame的行删除问题!首先先明确你的需求:你有一个双层索引的DataFrame,外层索引是names列表中的字符串,内层是datetime类型,想要删除每个外层索引分组下的第一行。

先重现你的示例场景

先构造出你提到的初始DataFrame:

import pandas as pd

# 构造示例数据
data = {
    'val1': [2.3, 3.6, 5.7, 7.2],
    'val2': [5.4, 8.2, 1.3, 3.8],
    'name': ['Tom', 'Tom', 'Jerry', 'Jerry'],
    'date': ['2018-01-01', '2018-01-02', '2018-02-18', '2018-02-19']
}
df = pd.DataFrame(data).set_index(['name', 'date'])
print(df)

输出结果:

val1  val2
name  date            
Tom   2018-01-01  2.3  5.4
      2018-01-02  3.6  8.2
Jerry 2018-02-18  5.7  1.3
      2018-02-19  7.2  3.8

你的目标是得到每个外层索引去掉首行后的结果:

val1  val2
name  date            
Tom   2018-01-02  3.6  8.2
Jerry 2018-02-19  7.2  3.8

分析你原来代码的问题

你尝试用循环遍历names,然后对df.loc[name]执行drop并设置inplace=True,但这里df.loc[name]返回的是原DataFrame的副本(或视图,取决于数据结构),修改这个副本不会影响原DataFrame,所以原数据不会有变化。

推荐的解决方案

这里给你三种可行的方法,按需选择:

方法1:用groupby.tail()(最简洁高效)

利用groupby按外层索引分组,然后用tail(1)获取每个组的最后一行(也就是去掉第一行),这个方法性能最优,代码最简洁:

df = df.groupby(level='name').tail(1)

方法2:用groupby.apply()(更灵活)

如果你的分组可能有不同行数(比如有的组有3行,想保留后面所有行),可以用apply结合iloc[1:]跳过第一行:

df = df.groupby(level='name').apply(lambda x: x.iloc[1:]).reset_index(level=0, drop=True)

这里reset_index(level=0, drop=True)是为了去掉apply后额外添加的外层索引层级,让结构回到原来的双层索引。

方法3:修正你的循环方法

如果你还是想用循环,可以直接在原DataFrame上删除对应的双层索引行:

names = ['Tom', 'Jerry']
for name in names:
    # 获取当前name对应的第一个内层索引
    first_inner_idx = df.loc[name].index[0]
    # 从原DataFrame中删除这个双层索引对应的行
    df = df.drop((name, first_inner_idx))

这个方法更直观,适合需要对每个组做自定义处理的场景,但如果数据量很大,性能不如前两种方法。

验证结果

不管用哪种方法,最终输出的DataFrame都会是你想要的目标结果。

内容的提问来源于stack exchange,提问作者KOB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:51:28