Pandas Timedelta分组求均值报错“No numeric types to aggregate”问询
解决pandas分组计算Timedelta均值的DataError问题
问题背景
你尝试通过pd.concat([A,B], axis = 1).groupby("status_reason")["closing_time"].mean()计算不同status_reason对应的closing_time(Timedelta类型)均值时,遇到了DataError: No numeric types to aggregate错误。单独计算整体均值正常,但分组后报错;转换为数值再转回时结果异常,筛选特定状态后分组仍报错,转换为秒计算的结果也和预期偏差极大。
核心原因
这个问题大概率是旧版本pandas对Timedelta类型的分组聚合支持不完善,或者直接转换数值时出现了整数溢出(Timedelta以纳秒存储,数值过大时超出int64范围会导致符号异常)。另外你之前用dt.seconds转换时,只保留了一天内的秒数,丢失了天数信息,这也是结果偏差的关键原因。
正确解决方案
方法1:转换为总秒数聚合(推荐,兼容所有版本)
把Timedelta转为包含完整时间信息的总秒数,分组求均值后再转回Timedelta,完美规避类型聚合问题:
# 拼接数据并生成总秒数字段 xxx = pd.concat([A, B], axis=1) xxx["closing_time_total_sec"] = xxx["closing_time"].dt.total_seconds() # 分组求均值后转回Timedelta result = xxx.groupby("status_reason")["closing_time_total_sec"].mean().apply(pd.to_timedelta, unit="s")
这里用dt.total_seconds()而不是dt.seconds,因为后者只提取单日秒数,会丢失跨天的天数信息,这正是你之前转换后结果偏差大的原因。
方法2:升级pandas版本
如果你的pandas版本低于1.3.0,对Timedelta的分组聚合支持存在缺陷,升级到最新稳定版后直接分组求均值就能正常运行:
# 先检查当前版本 import pandas as pd print(pd.__version__) # 直接分组计算均值 xxx = pd.concat([A, B], axis=1) result = xxx.groupby("status_reason")["closing_time"].mean()
方法3:手动遍历分组计算(适用于无法升级的场景)
如果没法升级版本,可以手动遍历每个分组,过滤无效值后计算均值:
xxx = pd.concat([A, B], axis=1) result = pd.Series(dtype="timedelta64[ns]") for reason, group in xxx.groupby("status_reason"): # 过滤NaT后计算有效均值 valid_times = group["closing_time"].dropna() if not valid_times.empty: result[reason] = valid_times.mean()
为什么之前的方法出问题?
pd.to_numeric(A):Timedelta以纳秒整数存储,当数值超过int64范围时会溢出,导致结果出现负数天数(比如你得到的-105558 days)。A.dt.seconds:仅提取单日的秒数,完全丢失了跨天的天数部分,所以结果只有小时分钟秒,和实际均值偏差极大。- 筛选后分组仍报错:旧版本pandas的分组聚合逻辑对Timedelta类型的识别有问题,即使子集有有效数据也无法被判定为可聚合类型。
内容的提问来源于stack exchange,提问作者Federico Dorato
相关产品推荐
相关产品推荐

