Python:在数据框列中将秒转换为日期时间格式

Posted

技术标签:

【中文标题】Python:在数据框列中将秒转换为日期时间格式【英文标题】:Python: Converting a seconds to a datetime format in a dataframe column 【发布时间】:2019-03-05 13:06:00 【问题描述】:

目前我正在使用一个大数据框 (12x47800)。十二列之一是由整数秒组成的列。我想将此列更改为包含 datetime.time 格式的列。计划是我尝试更改名为“depTime”的列的数据框。因为我希望它是一个 datetime.time 并且它可以跨越午夜,所以我添加了 if 语句。这“有效”但真的很慢,就像人们想象的那样。有没有更快的方法来做到这一点? 我当前的代码,我唯一可以工作的代码是:

for i in range(len(schedule)):
    t_sec = schedule.iloc[i].depTime
    [t_min, t_sec] = divmod(t_sec,60)
    [t_hour,t_min] = divmod(t_min,60)
    if t_hour>23:
        t_hour -= 23
    schedule['depTime'].iloc[i] = dt.time(int(t_hour),int(t_min),int(t_sec))

提前谢谢各位。

Ps:我对 Python 很陌生,所以如果有人能帮助我,我将非常感激 :)

【问题讨论】:

您能否提供一个简短的数据示例?例如schedule.head(20) 您确定您的列记录的是时间而不是持续时间吗?有一个区别,一天中的时间被限制为 [0-86400) 秒(闰秒为 86401),持续时间不受限制并且可以是负数。 Monty 在下午 10 点 3 分在 2 小时 35 分 5 秒内越过终点线 有一个时间和一个持续时间。您想在持续时间中使用 timedelta,而不是 time 【参考方案1】:

我正在添加一个比原始解决方案快得多的新解决方案,因为它依赖于 pandas 矢量化函数而不是循环(pandas 应用函数本质上是数据上的优化循环)。

我用与您的大小相似的样本对其进行了测试,差异在 778 毫秒到 21.3 毫秒之间。所以我绝对推荐新版本。

这两种解决方案都基于将秒整数转换为 timedelta 格式并将其添加到参考日期时间。然后,我只需捕获生成的日期时间的时间部分。

新(更快)选项:

import datetime as dt

seconds = pd.Series(np.random.rand(50)*100).astype(int) # Generating test data

start = dt.datetime(2019,1,1,0,0) # You need a reference point

datetime_series = seconds.astype('timedelta64[s]') + start

time_series = datetime_series.dt.time

time_series

原始(较慢)答案:

不是最优雅的解决方案,但可以解决问题。

import datetime as dt

seconds = pd.Series(np.random.rand(50)*100).astype(int) # Generating test data

start = dt.datetime(2019,1,1,0,0) # You need a reference point

time_series = seconds.apply(lambda x: start + pd.Timedelta(seconds=x)).dt.time

【讨论】:

这个解决方案似乎效果很好。由于我的代码需要实时(最终)运行,因此时间至关重要,而且运行速度非常快。您能否详细说明一下它的工作原理和原因? @Hestaron 我提出了一个似乎效果更好的新解决方案。建议你看看。 astype('timedelta64[ms]') 将数字转换为 毫秒,没有秒,然后添加任意纪元并使用 .dt.time 从中提取时间对象。除了使用毫秒而不是秒之外,它仅比使用 pd.to_datetime(seconds, unit='s').dt.time 稍快(586 us vs 714 us)。【参考方案2】:

您应该尽量不要对数据帧进行全面扫描,而是使用矢量化访问,因为它通常效率更高。

幸运的是,pandas 有一个功能可以完全满足您的要求,to_timedelta

schedule['depTime'] = pd.to_timedelta(schedule['depTime'], unit='s')

它并不是真正的日期时间格式,但它是 pandas 中的 datetime.timedelta 等价物,是处理时间的一种方便类型。您可以使用to_datetime,但将以接近 1970-01-01 的完整日期时间结束...

如果你真的需要datetime.time 对象,你可以这样获取它们:

schedule['depTime'] = pd.to_datetime(schedule['depTime'], unit='s').dt.time

但它们在 pandas 数据框中使用起来不太方便。

【讨论】:

这似乎是一个合适的解决方案,我用 to_datetime 进行了尝试。这似乎非常接近我想要实现的目标,但问题是我得到了一个 datetime.datetime,然后我仍然需要将其转换为 datetime.time 格式。我尝试使用 .time 但我得到的“系列”对象没有属性“时间”。我明白。从这一点开始,是否有一种简单的方法可以将 datetime.datetime 转换为 datetime.time? @Hestaron: time 属性可以在这里提供帮助:查看我的编辑。 如果有人出于性能原因,以这种方式转换为时间增量肯定优于转换为时间对象。

以上是关于Python:在数据框列中将秒转换为日期时间格式的主要内容,如果未能解决你的问题,请参考以下文章

怎么在Oracle中将时间戳转化为日期格式

在python中将时间转换为秒格式

在python中将Dataframe列转换为时间格式

怎么在Oracle中将时间戳转化为日期格式

如何在Oracle中将时间戳转化为日期格式

将日期时间数据的数据框列转换为 DD/MM/YYYY 字符串数据