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

如何在Pandas中聚合datetime64[ns]与float类型列的DataFrame

Pandas按选手分组聚合比赛时间与名次统计

原始数据

racerrace_time_1race_time_21st_Place2nd_Place
joe shmo0:24:12NaN10
joe shmoNaN0:32:4300
joe shmoNaN0:30:2101
sally sueNaN0:29:5410

需求

按racer字段分组,汇总每个选手的:

  • race_time_1:保留唯一的非空时长
  • race_time_2:所有有效时长的总和
  • 1st_Place/2nd_Place:获得对应名次的总次数

期望结果:

racerrace_time_1race_time_21st_Place2nd_Place
joe shmo0:24:121:03:0411
sally sueNaN0:29:5410

问题分析

直接使用df.groupby('racer').agg('sum')会因列类型不匹配报错:

  • 初始列均为object类型,无法直接聚合数值和时长
  • 转race_time为datetime64[ns](时间点类型)不适合时长统计,且分组时会被自动丢弃
  • 单独转名次列为数值类型,会导致时间列丢失

解决方案

1. 转换列类型

将时间列转为**时间差(timedelta)**类型(适合时长计算),名次列转为整数类型:

import pandas as pd

# 转换时间列为timedelta
df['race_time_1'] = pd.to_timedelta(df['race_time_1'])
df['race_time_2'] = pd.to_timedelta(df['race_time_2'])

# 转换名次列为整数
df['1st_Place'] = df['1st_Place'].astype(int)
df['2nd_Place'] = df['2nd_Place'].astype(int)

2. 指定分组聚合规则

针对不同列的需求设置对应的聚合函数:

# 定义各列的聚合逻辑
agg_rules = {
    # race_time_1取第一个非空值,无数据则返回空
    'race_time_1': lambda x: x.dropna().iloc[0] if not x.dropna().empty else pd.NaT,
    # race_time_2求和所有有效时长
    'race_time_2': 'sum',
    # 名次列统计总次数
    '1st_Place': 'sum',
    '2nd_Place': 'sum'
}

# 分组聚合,保留racer作为列而非索引
result_df = df.groupby('racer', as_index=False).agg(agg_rules)

3. 转换时间差为可读格式(可选)

将timedelta类型转为HH:MM:SS格式的字符串,方便展示:

def timedelta_to_str(td):
    if pd.isna(td):
        return None
    total_sec = int(td.total_seconds())
    hours = total_sec // 3600
    mins = (total_sec % 3600) // 60
    secs = total_sec % 60
    return f"{hours}:{mins:02d}:{secs:02d}"

# 应用格式转换
result_df['race_time_1'] = result_df['race_time_1'].apply(timedelta_to_str)
result_df['race_time_2'] = result_df['race_time_2'].apply(timedelta_to_str)

运行后即可得到符合预期的聚合结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:11:01