【问题标题】:Pandas dataframe Timedelta format: with days or with cumulative hoursPandas 数据框 Timedelta 格式:带天数或带累积小时数
【发布时间】:2020-09-01 17:15:32
【问题描述】:

我试图理解,这取决于 pandas 以“天”或累积小时数显示 Timedelta 值。

在下面的示例中,我采用 Timedelta 列并计算其累积和:

In [1]: import pandas as pd                                                                                                                                                      

In [2]: pd.__version__                                                                                                                                                           
Out[2]: '1.0.3'

In [3]: df = pd.DataFrame( 
   ...:     [ 
   ...:         "01:07:37", 
   ...:         "13:16:44", 
   ...:         "11:09:56", 
   ...:         "12:05:00", 
   ...:         "01:33:01", 
   ...:     ], 
   ...:     columns=["Duration"], 
   ...: )                                                                                                                                                                        

In [4]: df.loc[:, 'Duration'] = pd.to_timedelta(df['Duration']) 
   ...: df.loc[:, 'Cumulative'] = df['Duration'].cumsum() 
   ...:  
   ...: df                                                                                                                                                                       
Out[4]: 
  Duration      Cumulative
0 01:07:37 0 days 01:07:37
1 13:16:44 0 days 14:24:21
2 11:09:56 1 days 01:34:17
3 12:05:00 1 days 13:39:17
4 01:33:01 1 days 15:12:18

在结果数据框中,新列 (Cumulative) 显示“天”,而原始列 (Duration) 显示累计小时数。

两列的数据类型相同。

In [5]: df.dtypes                                                                                                                                                                
Out[5]: 
Duration      timedelta64[ns]
Cumulative    timedelta64[ns]
dtype: object

此外,当我查看第一行时,它显示“小时数”格式,但是,当我查看单个值时,它以 Timedelta('N days HH:MM:SS') 格式返回它们。

In [6]: df.iloc[0, :]                                                                                                                                                            
Out[6]: 
Duration     01:07:37
Cumulative   01:07:37
Name: 0, dtype: timedelta64[ns]

In [7]: df['Duration'][0], df['Cumulative'][0]                                                                                                                                   
Out[7]: (Timedelta('0 days 01:07:37'), Timedelta('0 days 01:07:37'))

所以我的问题是为什么会发生这种变化,我该如何控制它?

编辑

正如@Moosa Saadat 和@Quang Hoang 指出的那样,当任何 Timedelta 值超过24 小时阈值时,就会发生不同格式之间的转换。

由于我没有找到执行轮班的内置方法,这里有一个小帮助函数,它以累积小时数格式打印 Timedelta 值。

In [4]: def days_to_cumhours(timedelta): 
   ...:     hours = timedelta.components[0] * 24 + timedelta.components[1] 
   ...:  
   ...:     return f"{hours:0>2}:{timedelta.components[2]:0>2}:{timedelta.components[3]:0>2}"                                                                                                                                                                  

In [5]: df['Cumulative'].apply(days_to_cumhours)                                                                                                                                 
Out[5]: 
0    01:07:37
1    14:24:21
2    25:34:17
3    37:39:17
4    39:12:18
Name: Cumulative, dtype: object

【问题讨论】:

  • 这就是 pandas 在持续时间超过 1 天时选择显示timedelta 的方式。

标签: python pandas dataframe time timedelta


【解决方案1】:

为什么会发生这种变化?

时间字符串列表的所有值都小于 24 小时。这意味着他们都有day = 0。因此,当您打印 df 时,pandas 不会显示它。如果你改变一些值,比如说12:05:0025:05:00,你会得到下面的输出

         Duration      Cumulative
0 0 days 01:07:37 0 days 01:07:37
1 0 days 13:16:44 0 days 14:24:21
2 0 days 11:09:56 1 days 01:34:17
3 1 days 01:05:00 2 days 02:39:17
4 0 days 01:33:01 2 days 04:12:18

现在,由于我们在 Duration 列中有不同的 days,pandas 会显示它的值。

如何控制?

您不必担心输出的差异。何时,您需要获取可以使用返回命名元组的components() 函数的值

print(df['Duration'].iloc[0].components)

输出:

Components(days=0, hours=1, minutes=7, seconds=37, milliseconds=0, microseconds=0, nanoseconds=0)

【讨论】:

  • 是的,谢谢,实际上这很简单。我很困惑,因为并非所有值都超过一天。我仍然很好奇我是否可以以简单的方式将格式呈现为“累积小时数”格式。
  • @nocibambi 我不确定是否有任何内置函数。因此,您的辅助函数可能是唯一的方法。如果您只对小时数感兴趣,df['Duration'].iloc[0].total_seconds() / 3600 之类的就可以了。但是,同样,如果您正在寻找精确的时间,您的辅助函数会做得很好
  • @Moose Saadat 我主要关心的是演示,所以这就是我坚持这种格式的原因。否则,当然,我不会介意日子,或者确实可以计算小时数。我只是假设可能有一个内置的解决方案,因为这两种格式已经实现并正在使用中。
猜你喜欢
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 2016-05-23
  • 2015-06-29
相关资源
最近更新 更多