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

动态Pandas DataFrame中如何将秒值转换为HH:MM:SS格式时间间隔

速览

能否将该Pandas透视表DataFrame中的所有浮点数,从以秒为单位转换为HH:MM:SS格式的时间间隔?

当前透视表结构:

Name        Student A  Tutor
Date
2021-04-12       52.0   86.0
2021-04-13       13.0  113.0
2021-04-14        NaN   34.0
Average          32.5   77.6

期望的最终结果:

Name         Student A         Tutor
Date
2021-04-12    00:00:52      00:01:26
2021-04-13    00:00:13      00:01:53
2021-04-14                  00:00:34
Average       00:00:32      00:01:17

注意事项:

  • Tutor、Student A等列是动态生成的,无法通过列名固定引用,实际场景中表格可能存在多个学生列。
  • 尝试使用pd.to_timedelta时,所有转换结果都会自动添加"0 days"前缀,无法满足需求。
  • 原表格还包含总计列与总计行,此处为简化展示已将其移除。

详细说明

该透视表的构建流程如下:

import pandas as pd

df = pd.DataFrame({
    'Date': ['2021-04-12', '2021-04-12', '2021-04-13', '2021-04-13', '2021-04-14'],
    'Name': ['Tutor', 'Student A', 'Student A', 'Tutor', 'Tutor'],
    'duration_seconds': [86, 52, 13, 113, 34]
})

df的结构如下:

Date       Name  duration_seconds
0  2021-04-12      Tutor                86
1  2021-04-12  Student A                52
2  2021-04-13  Student A                13
3  2021-04-13      Tutor               113
4  2021-04-14      Tutor                34

执行分组操作:

grouped = df.groupby(['Name', 'Date']).sum()

得到分组结果:

duration_seconds
Name        Date
Student A   2021-04-12               52
            2021-04-13               13
Tutor       2021-04-12               86
            2021-04-13              113
            2021-04-14               34

转换为目标透视表格式:

pivoted = grouped.pivot_table(
    values='duration_seconds',
    index='Date',
    columns='Name'
)

得到透视结果:

Name        Student A  Tutor
Date
2021-04-12       52.0   86.0
2021-04-13       13.0  113.0
2021-04-14        NaN   34.0

添加平均值行:

pivoted.loc['Average'] = pivoted.mean()

得到添加平均值后的结果:

Name        Student A       Tutor
Date
2021-04-12       52.0   86.000000
2021-04-13       13.0  113.000000
2021-04-14        NaN   34.000000
Average          32.5   77.666667

以上为当前已完成的操作,最后一步需要将学生、导师类列下的所有数值转换为HH:MM:SS格式的时间间隔。

原本尝试的方案存在缺陷,所有转换结果都会被添加0 days 前缀,不符合需求:

pivoted.iloc[:].apply(pd.to_timedelta, unit='s')

解决方案

由于所有列都是动态生成的数值列,不需要硬编码列名,通过逐元素映射的方式即可完成转换,完全适配任意数量的动态列。

  1. 自定义转换函数:空值直接返回空字符串,有效秒数计算时分秒并补零为两位数格式
def convert_seconds(sec_val):
    # 匹配空值场景,返回空字符串而非00:00:00
    if pd.isna(sec_val):
        return ''
    # 截断小数秒,匹配示例的取整逻辑
    total_sec = int(sec_val)
    hours = total_sec // 3600
    minutes = (total_sec % 3600) // 60
    seconds = total_sec % 60
    # 格式化为统一的HH:MM:SS结构
    return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
  1. 对整个透视表应用转换,自动覆盖所有动态生成的列
# pandas >=2.1 直接使用.map,低版本替换为.applymap
final_df = pivoted.map(convert_seconds)
  1. 输出验证
print(final_df)

输出结果完全匹配预期:

Name         Student A         Tutor
Date
2021-04-12    00:00:52      00:01:26
2021-04-13    00:00:13      00:01:53
2021-04-14                  00:00:34
Average       00:00:32      00:01:17

补充:若所有时长均在单日以内,也可通过timedelta字符串拆分简化实现,自动去除days前缀:

final_df = (
    pivoted.apply(pd.to_timedelta, unit='s')
    .astype(str)
    .str.split(' ')
    .str[-1]
    .replace('NaT', '')
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 01:24:05