【问题标题】:Splitting timestamp column into separate date and time columns将时间戳列拆分为单独的日期和时间列
【发布时间】:2025-12-23 01:15:11
【问题描述】:

我有一个带有超过 1000 个时间戳(如下)的 pandas 数据框,我想循环访问:

2016-02-22 14:59:44.561776

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

感谢您的帮助

【问题讨论】:

  • '2016-02-22 14:59:44.561776'.split() 怎么样?
  • 仅限日期或时间的列将使用 Python 类型(datetime.date 和 datetime.time),因此功能会减少 - 例如那些系列没有dt accessor。此外,时区取决于日期,它们基本上只在一段时间内未定义。

标签: python pandas date datetime time


【解决方案1】:

有同样的问题,这对我有用。

假设数据集中的日期列名为“日期”

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

这将为您提供两列“日期”和“时间”以及拆分日期。

【讨论】:

  • 这对我有用,谢谢!我也不喜欢另一张海报中居高临下的 cmets 问“你为什么一开始就想做这件事”。有人可能需要在他们的代码中这样做的原因有很多!
  • 这将数据类型更改为对象!
  • @Jack,这是意料之中的。日期和时间部分不是日期时间对象,它们是 pandas(1.0.0 之前)表示为对象数据类型的字符串。
  • 好一个,比迭代更好。但是没有必要使用pd.to_datetime(除非该列只是字符串,而不是日期)。在使用 dt.datedt.time 之前,这会不必要地将日期时间转换为日期时间。
【解决方案2】:

我不知道你为什么要首先这样做,但如果你真的必须...

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

How to make an unaware datetime timezone aware in python

编辑

另一种仅在时间戳上循环一次而不是两次的替代方法:

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)

【讨论】:

  • 这就是我要找的。我现在收到此错误:AttributeError: 'str' object has no attribute 'date'。我需要将它们分开,因为我试图将值传递给另一个我没有编写的脚本 - 这是他使用的格式。
  • 这意味着您的数据被格式化为字符串而不是时间戳。试试pd.to_datetime(df.my_timestamp) 看看是否能正确转换。
  • 与上述相同的错误。但是,当我尝试其他用户的其他建议之一时,我得到一个“系列”错误代替 str。为什么会这样?
  • 要查看字符串的确切外观,您能否发布df.my_timestamp.iat[0] 的结果?这将返回您的第一个时间戳的内容。 df 显然是您的数据框的名称,my_timestamp 是您的日期列的名称。
  • 2016-02-21 21:19:44.797907
【解决方案3】:

我认为最简单的方法是使用熊猫系列的dt 属性。对于您的情况,您需要使用dt.datedt.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

【讨论】:

  • 对上述(尽管简单而优雅)解决方案的一个警告是,新的日期列现在是“对象”类型而不是 datetime64。 df['full_date'].dt.normalize() 保留 datetime64 格式,这会很有帮助。
【解决方案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

【讨论】:

    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

      试试

      s = '2016-02-22 14:59:44.561776'
      
      date,time = s.split()
      

      然后根据需要转换时间。

      如果你想进一步分割时间,

      hour, minute, second = time.split(':')
      

      【讨论】:

        【解决方案7】:

        试试这个:

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

        【讨论】:

          【解决方案8】:

          如果你想要一个单班轮

          ,除了@Alexander
          df['new_date'],df['new_time'] = zip(*[(d.date(), d.time()) for d in df['my_timestamp']])
          

          【讨论】: