将时间戳列拆分为独立的日期和时间列

62

我有一个包含超过1000个时间戳的pandas数据框(如下),我想循环遍历:

2016-02-22 14:59:44.561776

我很难将这个时间戳拆分成两个列 - “日期”和“时间”。日期格式可以保持不变,但时间需要转换为CST时区(包括毫秒)。

谢谢帮助。

9个回答

69

我曾经遇到同样的问题,以下方法对我有用。

假设你的数据集中日期列的名称为"date"。

import pandas as pd
df = pd.read_csv(file_path)

df['Dates'] = pd.to_datetime(df['date']).dt.date
df['Time'] = pd.to_datetime(df['date']).dt.time

这将为您提供两列,“日期”和“时间”,其中包含拆分后的日期。


51
我不确定你为什么一开始就想要做这件事,但如果你真的非做不可...
df = pd.DataFrame({'my_timestamp': pd.date_range('2016-1-1 15:00', periods=5)})

>>> df
         my_timestamp
0 2016-01-01 15:00:00
1 2016-01-02 15:00:00
2 2016-01-03 15:00:00
3 2016-01-04 15:00:00
4 2016-01-05 15:00:00

df['new_date'] = [d.date() for d in df['my_timestamp']]
df['new_time'] = [d.time() for d in df['my_timestamp']]

>>> df
         my_timestamp    new_date  new_time
0 2016-01-01 15:00:00  2016-01-01  15:00:00
1 2016-01-02 15:00:00  2016-01-02  15:00:00
2 2016-01-03 15:00:00  2016-01-03  15:00:00
3 2016-01-04 15:00:00  2016-01-04  15:00:00
4 2016-01-05 15:00:00  2016-01-05  15:00:00

转换为CST更棘手。我假设当前的时间戳是“无意识的”,即它们没有附加时区?如果没有,您希望如何进行转换?

更多详细信息,请参阅:

https://docs.python.org/2/library/datetime.html

如何使日期时间对象具有意识性(非空)

编辑

一个只在时间戳上循环一次而不是两次的替代方法:

new_dates, new_times = zip(*[(d.date(), d.time()) for d in df['my_timestamp']])
df = df.assign(new_date=new_dates, new_time=new_times)

编辑于2023年

现在我会这样做:

df = df.assign(
    new_date=df["my_timestamp"].dt.date, 
    new_time=df["my_timestamp"].dt.time
)

公平地说,assign 方法是在 2015 年 3 月 22 日发布的版本 0.16.0 中引入的,早在我最初回复这篇帖子的时候就已经存在了。

1
这个答案虽然被接受为正确答案,但没有充分利用pandas的向量函数。你不需要在数据框中循环遍历项目 - 这是人们喜欢使用它们的主要原因之一。你可以一次对整个系列(即列)进行操作,就像这个页面上的许多示例所展示的那样。 - Nesha25
@Nesha25 你说得太对了。这个回答相当老旧,我写下它之后学到了一些东西!我已经编辑了我的回复。 - Alexander

18

最简单的方法是使用 pandas.Series dt 访问器,它适用于具有 datetime dtype(请参阅 pd.to_datetime)的列。对于此情况,pd.date_range 创建一个具有 datetime dtype 的示例列,因此使用 .dt.date.dt.time

df = pd.DataFrame({'full_date': pd.date_range('2016-1-1 10:00:00.123', periods=10, freq='5H')})
df['date'] = df['full_date'].dt.date
df['time'] = df['full_date'].dt.time

In [166]: df
Out[166]:
                full_date        date             time
0 2016-01-01 10:00:00.123  2016-01-01  10:00:00.123000
1 2016-01-01 15:00:00.123  2016-01-01  15:00:00.123000
2 2016-01-01 20:00:00.123  2016-01-01  20:00:00.123000
3 2016-01-02 01:00:00.123  2016-01-02  01:00:00.123000
4 2016-01-02 06:00:00.123  2016-01-02  06:00:00.123000
5 2016-01-02 11:00:00.123  2016-01-02  11:00:00.123000
6 2016-01-02 16:00:00.123  2016-01-02  16:00:00.123000
7 2016-01-02 21:00:00.123  2016-01-02  21:00:00.123000
8 2016-01-03 02:00:00.123  2016-01-03  02:00:00.123000
9 2016-01-03 07:00:00.123  2016-01-03  07:00:00.123000

4
如果您的时间戳已经是 pandas 格式(不是字符串),那么:
df["date"] = df["timestamp"].date
dt["time"] = dt["timestamp"].time

如果您的时间戳是字符串类型,您可以使用datetime模块来解析它:
from datetime import datetime
data1["timestamp"] = df["timestamp"].apply(lambda x: \
    datetime.strptime(x,"%Y-%m-%d %H:%M:%S.%f"))

来源: http://pandas.pydata.org/pandas-docs/stable/timeseries.html

时间序列是 Pandas 中的一个核心领域,该领域提供了大量的功能来分析时间序列数据。本节将介绍 Pandas 的时间序列功能,并且用一些示例解释如何使用这些功能。


3
如果您的时间戳是一个字符串,您可以将它转换为一个datetime对象:
from datetime import datetime

timestamp = '2016-02-22 14:59:44.561776'
dt = datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S.%f')

从那时起,您可以将其转换为任何您喜欢的格式。


1

尝试

s = '2016-02-22 14:59:44.561776'

date,time = s.split()

然后根据需要转换时间。
如果您想进一步拆分时间,
hour, minute, second = time.split(':')

0

试试这个:

def time_date(datetime_obj):
    date_time = datetime_obj.split(' ')
    time = date_time[1].split('.')
    return date_time[0], time[0]

0
如果您的时间戳是字符串,您可以在拆分之前将其转换为Pandas时间戳。
#convert to pandas timestamp
data["old_date"] = pd.to_datetime(data.old_date)

#split columns
data["new_date"] = data["old_date"].dt.date
data["new_time"] = data["old_date"].dt.time

0
除了 @Alexander 之外,如果你想要一行代码。
df['new_date'],df['new_time'] = zip(*[(d.date(), d.time()) for d in df['my_timestamp']])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接