Python:将秒数转换为数据框列中的日期时间格式
Python: Converting a seconds to a datetime format in a dataframe column
目前我正在处理一个大数据框 (12x47800)。十二列之一是由整数秒组成的列。我想将此列更改为由 datetime.time 格式组成的列。 Schedule 是我的数据框,我在其中尝试更改名为 'depTime' 的列。因为我希望它是 datetime.time 并且它可以跨越午夜,所以我添加了 if 语句。这 'works' 但是真的很慢,可以想象。有没有更快的方法来做到这一点?
我当前的代码,我唯一可以使用的代码是:
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 的新手,所以如果有人能帮助我,我将不胜感激:)
我正在添加一个比原始解决方案快得多的新解决方案,因为它依赖于 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
您应该尽量不要对数据帧进行全面扫描,而是使用矢量化访问,因为它通常效率更高。
幸运的是,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 数据框中使用它们不太方便。
目前我正在处理一个大数据框 (12x47800)。十二列之一是由整数秒组成的列。我想将此列更改为由 datetime.time 格式组成的列。 Schedule 是我的数据框,我在其中尝试更改名为 'depTime' 的列。因为我希望它是 datetime.time 并且它可以跨越午夜,所以我添加了 if 语句。这 'works' 但是真的很慢,可以想象。有没有更快的方法来做到这一点? 我当前的代码,我唯一可以使用的代码是:
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 的新手,所以如果有人能帮助我,我将不胜感激:)
我正在添加一个比原始解决方案快得多的新解决方案,因为它依赖于 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
您应该尽量不要对数据帧进行全面扫描,而是使用矢量化访问,因为它通常效率更高。
幸运的是,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 数据框中使用它们不太方便。