【问题标题】:Splitting timestamp column into separate date and time columns将时间戳列拆分为单独的日期和时间列
【发布时间】:2016-06-06 08:42:09
【问题描述】:

我有一个带有超过 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】:

试试

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

date,time = s.split()

然后根据需要转换时间。

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

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

【讨论】:

    【解决方案2】:

    试试这个:

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

    【讨论】:

      【解决方案3】:

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

      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
      【解决方案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】:

          我认为最简单的方法是使用熊猫系列的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 格式,这很有帮助。
          【解决方案7】:

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

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

          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 之前,这会不必要地将日期时间转换为日期时间。
          【解决方案8】:

          如果你想要一个单班轮

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

          【讨论】:

            猜你喜欢
            • 2021-07-27
            • 1970-01-01
            • 2018-08-28
            • 2016-12-07
            • 2018-01-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多