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

使用pandas处理含NA值的分组取首条最大值行报错求助

Pandas分组取最大值首行并保留NA行的问题解决

问题场景

原DataFrame定义

import pandas as pd
df = pd.DataFrame(
    {
        1: ['a', 'a', 'a', 'b', 'b', 'c', 'd'],
        2: ['x', 'y', 'y', 'x', 'y', pd.NA, 'x'],
        3: [10, 8, 8, 10, 7, pd.NA, 0],
        4: [4, 4, 5, 7, 8, pd.NA, 0]
    },
)

原始数据展示

1     2     3     4
0  a     x    10     4
1  a     y     8     4
2  a     y     8     5
3  b     x    10     7
4  b     y     7     8
5  c  <NA>  <NA>  <NA>
6  d     x     0     0

需求说明

按列1和列2分组,保留每组中列3为最大值的首条行,同时完整保留含NA值的行,预期结果如下:

1     2     3     4
0  a     x    10     4
1  a     y     8     4
3  b     x    10     7
4  b     y     7     8
5  c  <NA>  <NA>  <NA>
6  d     x     0     0

尝试的方法及报错

已执行列类型转换:

df[3] = pd.to_numeric(df[3])

尝试用groupby([1, 2], dropna=False)分组,结合loc和idxmax实现需求:

df2: pd.DataFrame = df.loc[
    df.groupby([1, 2], dropna=False)[3].idxmax()
]

触发异常:KeyError: '[nan] not in index'

问题原因

这个错误确实和pandas issue #52234直接相关——在pandas 2.0.x版本中,当分组包含NA值且设置dropna=False时,idxmax()会返回NaN作为该分组的索引值,但df.loc[]无法识别NaN作为行索引,因此抛出KeyError。另外,分组后直接取max()会丢失其他列数据,不符合需求。

解决方案

以下两种方法均可解决问题:

方法1:用transform标记最大值首行

先给每个分组标记出列3为最大值的行,再筛选并保留每组首条,同时保留NA行:

# 标记每组中列3为最大值的行,全NA分组直接标记为True
df['is_max'] = df.groupby([1, 2], dropna=False)[3].transform(
    lambda x: x == x.max() if not x.isna().all() else True
)
# 筛选标记行,每个分组只取首条
result = df[df['is_max']].groupby([1, 2], dropna=False).first().reset_index(drop=True)
# 删除临时标记列
result = result.drop(columns='is_max')

方法2:分离NA与非NA分组处理

先处理非NA分组的最大值首行,再单独提取NA行合并:

# 分离非NA行和全NA行
non_na_df = df.dropna(subset=[3])
na_df = df[df[3].isna()]

# 非NA分组取最大值首行
non_na_result = non_na_df.loc[non_na_df.groupby([1, 2])[3].idxmax()]

# 合并结果并按原索引排序
result = pd.concat([non_na_result, na_df]).sort_index()

两种方法都能得到预期结果,且规避了idxmax()返回NaN导致的KeyError问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:24:53