Pandas groupby分组后如何基于指定列最值返回另一列对应值
Pandas分组取列最值对应另一列值实现方案
核心需求为按item分组后,定位到每组内thing1取最小值、最大值的行,提取对应行的thing2值,以下是两种可直接复用的实现方案:
方案1:最值索引匹配(优先使用,性能最优)
利用pandas Series自带的idxmin()/idxmax()方法,直接拿到分组内thing1最值对应的原始行索引,再通过索引匹配取对应thing2值,不需要全表排序,大数据量下性能优势明显。
示例代码:
import pandas as pd import numpy as np # 测试数据(和描述样例一致) df = pd.DataFrame({ 'item': ['a', 'a', 'b', 'b', 'c', 'c'], 'thing1': [2, 5, 4, 7, 1, 3], 'thing2': [10, 20, 30, 50, 0, 100] }) # 核心聚合逻辑 result = df.groupby('item', as_index=False).agg( # 如需同时输出thing1的最值,放开下面两行注释即可 # thing1_min = ('thing1', 'min'), thing2_at_thing1_min = ('thing1', lambda col: df.loc[col.idxmin(), 'thing2']), # thing1_max = ('thing1', 'max'), thing2_at_thing1_max = ('thing1', lambda col: df.loc[col.idxmax(), 'thing2']) )
运行后c组返回值为thing2_at_thing1_min=0、thing2_at_thing1_max=100,完全匹配预期结果。
注意:如果同组内
thing1的最值存在多行重复值,该方法默认取首次出现的行对应的thing2值。
方案2:排序后取首尾(逻辑简单,适合小数据集)
如果数据量在十万行以内,可以先对数据排序,分组后直接取组内首行、尾行的thing2值,代码可读性更高:
# 先按item分组,组内按thing1升序排列 df_sorted = df.sort_values(by=['item', 'thing1']) # 组内首行对应thing1最小值,尾行对应thing1最大值 result = df_sorted.groupby('item', as_index=False).agg( thing2_at_thing1_min = ('thing2', 'first'), thing2_at_thing1_max = ('thing2', 'last') )
该方案返回结果和方案1完全一致,缺点是全表排序在百万级以上数据量时耗时明显高于方案1。
避坑说明
之前使用的df.groupby('item').agg({'thing1' : [np.min, np.max]})只能直接计算thing1列本身的最值,无法关联同一行其他列的值;注意不要和直接取thing2列min/max的写法混淆——后者取的是thing2自身的最值,不是thing1取最值时对应的thing2值。
内容的提问来源于stack exchange,提问作者manny
相关产品推荐
相关产品推荐

