【问题标题】:Pandas: Difference of time columns returns -1 days熊猫:时间列的差异返回-1天
【发布时间】:2020-05-12 00:26:58
【问题描述】:

我有一个包含两次列的数据框 (dtype = timedelta64[ns])
看起来像:

START_TIME      RESTORE_TIME
17:17:00        18:46:00
20:07:00        00:44:00
20:07:00        00:45:00
14:16:00        15:50:00
14:16:00        17:55:00

我创建了另一个列,它采用了 RESTORE_TIMESTART_TIME 的差异。我使用了以下命令:

df['Diff']=df['RESTORE_TIME'] - df2['START_TIME']

我的输出数据框如下所示:

  START_TIME      RESTORE_TIME      Diff
  17:17:00        18:46:00          01:29:00
  20:07:00        00:44:00 -1 days +04:37:00
  20:07:00        00:45:00 -1 days +04:38:00
  14:16:00        15:50:00          01:34:00
  14:16:00        17:55:00          03:39:00

我不确定为什么Diff 列在某些值中显示-1 days?当我对 Diff 列执行某些计算时,它没有返回所需的值。例如,如果我取Diff 列的平均值(通过使用命令np.mean(df['Diff']),它返回Timedelta('-1 days +17:35:24'),这显然不是这种情况。谁能指导我如何纠正这个问题?

【问题讨论】:

  • 您确定您的列是timedelta64[ns] 类型的吗?这对我来说不会立即有意义,因为您不知道这种情况下的参考日期。键入 datetime.time 不会让它变得更好,因为它有同样的缺失参考的问题。

标签: python python-3.x pandas dataframe datetime


【解决方案1】:

为了说明这里发生了什么,让我们创建一个虚拟df,列类型为timedelta64[ns]

from datetime import timedelta
import pandas as pd

# example df with time columns
df = pd.DataFrame({'START_TIME': pd.Series(pd.to_datetime(['17:17:00','20:07:00','20:07:00','14:16:00','14:16:00'])).dt.time,
                   'RESTORE_TIME': pd.Series(pd.to_datetime(['18:46:00','00:44:00','00:45:00','15:50:00','17:55:00'])).dt.time})
# to timedelta
df = df.applymap(lambda t: timedelta(hours=t.hour, minutes=t.minute, seconds=t.second))

如果您查看 timedelta 的 total_seconds,如果您取两列的差值,就会清楚发生了什么:

df.applymap(lambda t: t.total_seconds())
#    START_TIME  RESTORE_TIME
# 0     62220.0       67560.0
# 1     72420.0        2640.0
# 2     72420.0        2700.0
# 3     51360.0       57000.0
# 4     51360.0       64500.0

例如2640.0 - 72420.0 显然是否定的,'-1 days +04:37:00' 表示为 timedelta。

类似于@Ehsan 的回答,如果 'START_TIME' > 'RESTORE_TIME',您可以应用一个简单的函数来添加一天:

def timedelta_diff(t0, t1):
    """
    calculate difference between two timedeltas t0 and t1.
    if t1 < t0, assume that 1 day has to be added to t1.
    """
    if t1 < t0:
        t1 += timedelta(days=1)
    return t1-t0

df['DIFF'] = df.apply(lambda x: timedelta_diff(x.START_TIME, x.RESTORE_TIME), axis=1)
# df['DIFF']
# 0   01:29:00
# 1   04:37:00
# 2   04:38:00
# 3   01:34:00
# 4   03:39:00
# Name: DIFF, dtype: timedelta64[ns]

【讨论】:

    【解决方案2】:

    如果是午夜,您需要在代码中添加以下内容:

    from datetime import timedelta
    if df['Diff'].days < 0:
        df['Diff'] = timedelta(days=0,
                    seconds=df['Diff'].seconds, microseconds=df['Diff'].microseconds)
    

    【讨论】:

      【解决方案3】:

      没错。发生这种情况是因为这两行的第二列 (RESTORE_TIME) 显示了午夜之后的时间。这意味着新的一天已经开始。 我可以考虑使用条件来避免这种情况,例如你可以说

      if df2['START_TIME']< df['RESTORE_TIME']:
         df['Diff']= df2['START_TIME'] - df['RESTORE_TIME'] 
      else:
         df['Diff']= df['RESTORE_TIME'] - df2['START_TIME']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-17
        • 1970-01-01
        • 2019-08-23
        • 1970-01-01
        • 2019-01-03
        • 2018-10-14
        • 1970-01-01
        相关资源
        最近更新 更多