【问题标题】:How to convert seconds to a custom interval format in a dynamic Pandas DataFrame?如何在动态 Pandas DataFrame 中将秒数转换为自定义间隔格式?
【发布时间】:2021-07-20 03:29:41
【问题描述】:

tl;博士

是否可以将此 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

注意事项:

  • TutorStudent A 列是动态的,因此我无法通过名称引用它们。实际上,表中可能有多个学生。
  • 我在申请 pd.to_timedelta 时运气不佳,因为它的前缀是“0 天”。
  • 该表还包含总列和总行,但为了清楚起见,我已将其删除。

长读

这就是数据透视表的构建方式:

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')

【问题讨论】:

    标签: python-3.x pandas dataframe pivot-table


    【解决方案1】:
    def strfdelta(tdelta, fmt):
        d = {"days": tdelta.days}
        d["hours"], rem = divmod(tdelta.seconds, 3600)
        d["minutes"], d["seconds"] = divmod(rem, 60)
        return fmt.format(**d)
    
    
    df = df.apply(
        lambda x: [
            strfdelta(
                pd.Timedelta(seconds=v),
                "{hours:02d}:{minutes:02d}:{seconds:02d}",
            )
            if pd.notna(v)
            else ""
            for v in x
        ],
    )
    print(df)
    

    打印:

               Student A     Tutor
    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
    

    strfdelta 函数来自Formatting timedelta objects

    【讨论】:

    • 太棒了,非常感谢你的帮助,Andrej!
    猜你喜欢
    • 2017-01-08
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 2016-09-24
    • 2021-02-24
    • 1970-01-01
    相关资源
    最近更新 更多