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

如何在Pandas中获取分组最小值及对应行的列值、分组最小日期及对应列值

Pandas分组获取最小值/最小日期及对应列值问题解答

我来帮你搞定这两个Pandas分组相关的问题,先从第一个问题说起,再重点解决你遇到的第二个问题的代码bug~


问题1:如何在Pandas中获取分组的最小值,以及该最小值所在行对应某一列的数值?

假设你有一个DataFrame,需要按某列(比如group_col)分组,找到另一列(比如value_col)的最小值,同时获取该最小值所在行的第三列(比如target_col)的数值,这里有两种常用的实现方法:

方法1:用idxmin()定位行索引后提取

idxmin()会返回每个分组中value_col最小值对应的行索引,我们可以通过这个索引直接提取目标列的值,再合并回原DataFrame:

import pandas as pd

# 示例数据
data = {'group_col': ['A', 'A', 'B', 'B'], 'value_col': [3, 1, 5, 2], 'target_col': ['x', 'y', 'm', 'n']}
df = pd.DataFrame(data)

# 获取每个分组中value_col最小的行索引
min_idx = df.groupby('group_col')['value_col'].idxmin()
# 提取对应的最小值和目标列值
result = df.loc[min_idx, ['group_col', 'value_col', 'target_col']].rename(columns={'value_col': 'min_value'})
# 合并回原数据(如果需要保留所有行)
df = df.merge(result, on='group_col', suffixes=('', '_min'))

方法2:结合transform()和布尔索引

先用transform('min')得到每个分组的最小值,再筛选出对应行的目标列值,最后将结果广播到整个分组:

df['min_value'] = df.groupby('group_col')['value_col'].transform('min')
# 筛选出最小值所在行的target_col,再按分组广播到所有行
df['target_min'] = df.loc[df['value_col'] == df['min_value'], 'target_col'].groupby(df['group_col']).transform('first')

问题2:按分组获取最小日期,并获取该最小日期所在行对应另一列的数值(解决你的代码错误)

先分析你现有代码的问题:你使用df.groupby('type')['date_value','sum_col'].transform('min')时,Pandas会分别对date_value和sum_col两列取分组内的最小值,所以new_sum_col得到的是每个分组sum_col的最小值(比如分组B的sum_col最小值是2),而不是你期望的「最小日期对应行的sum_col值」。

下面是三种正确的解决方案:

方法1:通过idxmin()定位最小日期的行,再合并回原数据

这是最直观的方法,先找到每个分组中最小日期的行索引,提取对应的日期和sum_col,再和原DataFrame合并:

import pandas as pd

data = {'date_value': ['2014-06-22', '2014-06-24', '2014-06-25', '2014-06-25', '2014-07-02', '2014-07-06', '2014-07-05', '2014-07-27'], 'type': ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'C'], 'sum_col': [1, 2, 3, 5, 4, 3, 2, 1]}
df = pd.DataFrame(data, columns=['date_value', 'type', 'sum_col'])
df['date_value'] = pd.to_datetime(df['date_value'])

# 获取每个分组中date_value最小的行索引
min_date_idx = df.groupby('type')['date_value'].idxmin()
# 提取对应的min_date和new_sum_col
min_info = df.loc[min_date_idx, ['type', 'date_value', 'sum_col']].rename(columns={'date_value': 'min_date', 'sum_col': 'new_sum_col'})
# 合并回原DataFrame
df = df.merge(min_info, on='type')

运行后会得到你期望的结果:

date_value type  sum_col   min_date  new_sum_col
0 2014-06-22    A        1 2014-06-22            1
1 2014-06-24    A        2 2014-06-22            1
2 2014-06-25    A        3 2014-06-22            1
3 2014-06-25    B        5 2014-06-25            5
4 2014-07-02    B        4 2014-06-25            5
5 2014-07-06    B        3 2014-06-25            5
6 2014-07-05    B        2 2014-06-25            5
7 2014-07-27    C        1 2014-07-27            1

方法2:用transform()结合索引匹配

如果你不想用merge,可以先计算每个分组的最小日期,再通过索引匹配找到对应行的sum_col:

# 先添加min_date列
df['min_date'] = df.groupby('type')['date_value'].transform('min')
# 获取每个分组最小日期对应的sum_col,再通过type映射到每一行
min_sum = df.loc[df['date_value'] == df['min_date'], ['type', 'sum_col']].set_index('type')['sum_col']
df['new_sum_col'] = df['type'].map(min_sum)

方法3:自定义聚合函数

通过groupby.agg()自定义聚合逻辑,直接计算每个分组的最小日期和对应sum_col,再合并:

agg_result = df.groupby('type').agg(
    min_date=('date_value', 'min'),
    new_sum_col=('sum_col', lambda x: df.loc[x.index[df.loc[x.index, 'date_value'] == df.loc[x.index, 'date_value'].min()], 'sum_col'].iloc[0])
)
df = df.merge(agg_result, on='type')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 21:27:39