Pandas多级列场景下按一级分组取最大值对应列名生成新列问题
错误原因及原理说明
直接操作报错的核心原因
报错ValueError: No axis named 1 for object type Series的根源是pandas GroupBy的轴规则限制:
- 原DataFrame的多级索引在列上,要按一级列分组必须指定
groupby(level=0, axis=1),此时每个分组是对应一级列下的子DataFrame,保留所有行,仅包含该一级索引下的二级列。 - GroupBy对象的聚合方法(如
idxmax)的运算轴由分组时的axis参数决定,默认对分组轴的垂直方向做聚合,不支持在聚合时额外传入axis参数覆盖。如果强行给idxmax加axis=1,pandas会将分组内的每一行作为单维度Series处理,而Series只有axis=0维度,不存在axis=1,因此直接抛出错误。
转置操作的作用
你用的转置方案刚好规避了这个轴限制:
- 转置后原多级列索引转为多级行索引,原行索引转为列索引
- 此时按
level=0分组为按行分组,无需指定axis=1,调用idxmax时默认沿行方向聚合,对每一列(对应原DataFrame的每一行)返回该组最大值对应的行索引(即一级+二级列名组成的元组) - 再次转置后即可得到每行对应各一级列的最大值索引结果,后续拼接即可得到目标字段。
无需转置的实现方案
如果不想用转置,也可以通过分组后显式apply指定行方向取idxmax实现,效果一致:
df['results'] = df.replace(0, np.nan)\ .groupby(level=0, axis=1)\ .apply(lambda x: x.idxmax(axis=1))\ .T\ .apply(lambda x: '&'.join([f'{lev1}{lev2}' for lev1, lev2 in x.dropna()]), axis=1)
内容的提问来源于stack exchange,提问作者Nagib
相关产品推荐
相关产品推荐

