【问题标题】:Get the time spent since midnight in dataframe获取自午夜以来在数据框中花费的时间
【发布时间】:2019-07-14 04:34:12
【问题描述】:

我有一个数据框,其中有一列时间戳类型。我想查找自午夜以来经过的时间(以秒为单位)作为新列。如何以简单的方式做到这一点?

例如: 输入:

samples['time']
2018-10-01 00:00:01.000000000
2018-10-01 00:00:12.000000000

type(samples['time'].iloc[0])

<class 'pandas._libs.tslib.Timestamp'>

输出:

samples['time_elapsed']
1
12

【问题讨论】:

标签: pandas python-datetime timedelta


【解决方案1】:

当前的答案要么太复杂,要么太专业。

samples = pd.DataFrame(data=['2018-10-01 00:00:01', '2018-10-01 00:00:12'], columns=['time'], dtype='datetime64[ns]')

samples['time_elapsed'] = ((samples['time'] - samples['time'].dt.normalize()) / pd.Timedelta('1 second')).astype(int)

print(samples)
                 time  time_elapsed
0 2018-10-01 00:00:01             1
1 2018-10-01 00:00:12            12
  • normalize() 从日期时间中删除时间部分(将时钟移回午夜)。
  • pd.Timedelta('1 s') 设置度量单位,即 timedelta 中的秒数。
  • .astype(int) 将十进制秒数转换为 int。如果愿意,请使用圆形功能。

【讨论】:

    【解决方案2】:

    请注意,每一行中的日期部分可能是其他的(不是来自一个 和同一天),所以你不能采取任何“基准日期”(午夜) 对于整个 DataFrame,就像在其他解决方案之一中看到的那样。

    我的意图也不是“污染”源 DataFrame 与任何中间列,例如时间(实际上是日期和时间) 作为字符串转换为“真”日期时间

    那么我的提议是:

    • 将 DateTime 字符串转换为 DateTime,
    • 花点时间,
    • 从小时/分钟/秒计算秒数 部分。

    上述所有步骤都在一个专用函数中。

    所以要完成任务,定义一个函数:

    def secSinceMidnight(datTimStr):
        tt = pd.to_datetime(datTimStr).time()
        return tt.hour * 3600 + tt.minute * 60 + tt.second
    

    然后调用:

    samples['Secs'] = samples.time.apply(secSinceMidnight)
    

    对于源数据:

    samples = pd.DataFrame(data=[
        [ '2018-10-01 00:00:01' ], [ '2018-10-01 00:00:12' ],
        [ '2018-11-02 01:01:10' ], [ '2018-11-04 03:02:15' ] ],
        columns = ['time']);
    

    当你打印结果时,你会看到:

                      time   Secs
    0  2018-10-01 00:00:01      1
    1  2018-10-01 00:00:12     12
    2  2018-11-02 01:01:10   3670
    3  2018-11-04 03:02:15  10935
    

    【讨论】:

      【解决方案3】:

      在 Pandas 中执行此操作非常简单!

      midnight = pd.Timestamp('2018-10-01 00:00:00')
      print(pd.Timestamp('2018-10-01 00:00:01.000000000') - midnight).seconds
      >
      1
      

      通过扩展,我们可以在 Pandas 系列中使用 apply

      samples = pd.DataFrame(['2018-10-01 00:00:01.000000000', '2018-10-01 00:00:12.000000000'], columns=['time'])
      samples.time = pd.to_datetime(samples.time)
      midnight = pd.Timestamp('2018-10-01 00:00:00')
      samples['time_elapsed'] = samples['time'].apply(lambda x: (x - midnight).seconds)
      samples
      >
              time    time_elapsed
      0   2018-10-01 00:00:01     1
      1   2018-10-01 00:00:12     12
      

      请注意,here 的答案使用了另一种方法:将时间戳与转换为日期的自身进行比较。这会将所有时间数据归零,因此相当于当天的午夜。此方法的性能可能稍高一些。

      【讨论】:

      • 这个答案假设所有日期时间都在一个声明的日期(2018-10-01)。
      【解决方案4】:

      我在我的一个项目中遇到了同样的问题,我是这样解决的(假设您的 time 列已转换为 Timestamp):

      (samples['time'] - samples['time'].dt.normalize()) / pd.Timedelta(seconds=1)
      

      这种方法的美妙之处在于,您可以更改最后一部分以获取经过的秒数、分钟数、小时数或天数:

      ... / pd.Timedelta(seconds=1) # seconds elapsed
      ... / pd.Timedelta(minutes=1) # minutes elapsed
      ... / pd.Timedelta(hours=1)   # hours elapsed
      ... / pd.Timedelta(days=1)    # days elapsed
      

      【讨论】:

        【解决方案5】:
        datetime = samples['time']
        
        (datetime - datetime.dt.normalize()).dt.total_seconds()
        

        【讨论】:

          【解决方案6】:

          我们可以做到:

              samples['time'].dt.hour * 3600 + 
              samples['time'].dt.minute * 60 + 
              samples['time'].dt.second
          

          【讨论】:

            猜你喜欢
            • 2013-09-29
            • 1970-01-01
            • 2012-06-23
            • 1970-01-01
            • 1970-01-01
            • 2019-07-10
            • 2021-12-08
            • 2019-12-11
            • 1970-01-01
            相关资源
            最近更新 更多