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

Pandas:对GroupBy对象执行列求和时出现意外负值或NaT问题

解决GroupBy聚合timedelta时结果异常的问题

嘿,这个问题我之前处理过类似的情况,咱们来一步步分析原因和解决方案:

问题根源

你遇到的核心问题大概率和pandas版本对timedelta类型的GroupBy聚合支持不完善有关,尤其是在pandas 1.3.0之前的版本:

  • pandas内部会把timedelta存储为int64类型(单位是纳秒),当聚合时如果总和超出int64的取值范围(约±9e18纳秒,相当于约292年),就会触发整数溢出,导致出现负的timedelta值。
  • 单个组调用sum()是直接对Series进行计算,而GroupBy对象直接调用sum()是批量执行聚合逻辑,旧版本中这两种路径的处理逻辑存在差异,导致结果不一致。
  • 另外dropna=False的设置如果包含Version为nan的组,旧版本pandas对这类组的timedelta聚合也容易出现异常。

解决方案

方案1:升级pandas版本

首先检查你当前的pandas版本:

import pandas as pd
print(pd.__version__)

如果版本低于1.3.0,建议升级到最新稳定版:

pip install --upgrade pandas

pandas在1.3.0版本后修复了多个timedelta聚合相关的bug,包括GroupBy场景下的溢出和结果不一致问题。

方案2:转换为数值类型后聚合(兼容旧版本)

如果暂时无法升级pandas,可以先把timedelta转换为总秒数(float64类型,避免溢出),聚合后再转换回timedelta:

# 将Elapsed Time转换为总秒数
df_runs['elapsed_seconds'] = df_runs['Elapsed Time'].dt.total_seconds()

# 按Version分组求和
sum_result = df_runs.groupby(['Version'], dropna=False)['elapsed_seconds'].sum()

# 将求和结果转换回timedelta类型
sum_result = pd.to_timedelta(sum_result, unit='s')

这种方法绕开了直接聚合timedelta的问题,同时float64的取值范围远大于int64,不会出现溢出导致负数的情况。

验证方法

你可以用以下步骤验证结果是否正确:

  • 用单个组的Elapsed Time.dt.total_seconds().sum()计算结果,和GroupBy转换后的结果对比,应该完全一致。
  • 检查转换后的timedelta是否正常,不会出现负数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 11:02:32