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

Pandas Groupby:如何从分组中提取首个、末尾或首个非NaN值

解决Pandas groupby.agg聚合时保留非数值列的问题

核心问题分析

你遇到的问题本质是:agg()聚合时,未指定非数值列的聚合规则导致信息丢失;而用head/tail无效,是因为这两个方法返回的是Series而非单个标量,不符合agg()对聚合函数的要求(需返回单个值)。下面针对你的两个场景给出具体解决方案:


场景1:1分钟时间重采样保留Name列

针对含DateTime索引、Name、Price、Volume的DataFrame,只需在agg()中为Name指定first/last(根据需求选择,若每组Name一致,用first即可):

# 假设df的DateTime是索引
1_min_df = df.groupby(pd.Grouper(freq="1T")).agg({
    'Name': 'first',  # 保留每组第一个Name值,若每组Name唯一/一致更合适
    'Price': 'ohlc',
    'Volume': 'sum'
})

如果需要保留每组的最后一个Name值,把'first'换成'last'即可。


场景2:按累计Volume分组保留首行DateTime

首先要确保DateTime是普通列(如果是索引,先转成列),然后同样用first聚合DateTime:

# 若DateTime是索引,先转为列
df_concat['DateTime'] = df_concat.index

# 按累计Volume分组并聚合
vol_1000_df = df_concat.groupby(bar(np.cumsum(df_concat['Volume']), 1000)).agg({
    'DateTime': 'first',  # 保留每组的首个DateTime值
    'Name': 'first',      # 按需保留Name的首/尾值
    'Price': 'ohlc',
    'Volume': 'sum'
})

进阶:提取非数值列的首个非NaN值

如果非数值列存在NaN,想提取每组第一个非空值,可以自定义聚合函数:

import numpy as np

def first_non_nan(x):
    filtered = x.dropna()
    return filtered.iloc[0] if not filtered.empty else np.nan

# 使用自定义函数聚合
vol_1000_df = df_concat.groupby(bar(np.cumsum(df_concat['Volume']), 1000)).agg({
    'Name': first_non_nan,
    'DateTime': 'first',
    'Price': 'ohlc',
    'Volume': 'sum'
})

关键注意事项

  • 避免用head/tail作为聚合规则:这两个方法返回的是Series,agg()无法将其解析为单个值,会导致报错或不符合预期
  • 索引列的处理:若要保留索引信息,先通过reset_index()或直接赋值将索引转为普通列,再进行聚合
  • 一致性验证:如果非数值列(如Name)在每组内值一致,用first/last完全没问题;若值不一致,需提前确认业务需求(取首/尾还是其他规则)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:20:22