【问题标题】:How to convert timedelta to time of day in pandas?如何将 timedelta 转换为 pandas 中的时间?
【发布时间】:2016-04-02 19:10:51
【问题描述】:

我有一个 SQL 表,其中包含 mySQL time 类型的数据,如下所示:

time_of_day
-----------
   12:34:56

然后我使用pandas 读取表格:

df = pd.read_sql('select * from time_of_day', engine)

查看df.dtypes 产生:

time_of_day timedelta64[ns]

我的主要问题是,当我将我的df 写入 csv 文件时,输出的数据一团糟,而不是本质上看起来像我的 SQL 表:

time_of_day
0 days 12:34:56.000000000

我想(显然)将此记录存储为 time,但我在 pandas 文档中找不到任何关于时间 dtype 的内容。

pandas 是不是故意缺少这个功能?有没有办法解决我的问题而不需要 janky 数据转换?

似乎这应该是初级的,但我很困惑。

【问题讨论】:

  • pandas.to_datetime 给出了什么?
  • 它返回1970-01-01 12:34:56
  • 当 mysql 列是 TIME 类型时,pandas 返回 TimeDelta 时同样的问题。当列类型为 DATETIME 时,我没有得到这种行为。 Pandas read_sql 方法中没有解析时间的选项。
  • 我认为的问题是 NumPy 没有实现 time 类,而 Pandas 是基于 NumPy 构建的。所以不要认为这对 Pandas 来说是自然的。

标签: python pandas datetime time timedelta


【解决方案1】:

这是一个 hack,但您可以提取组件来创建一个字符串并将该字符串转换为 datetime.time(h,m,s) 对象

def convert(td):
    time = [str(td.components.hours), str(td.components.minutes), 
    str(td.components.seconds)]
    return datetime.strptime(':'.join(time), '%H:%M:%S').time()

df['time'] = df['time'].apply(lambda x: convert(x))

【讨论】:

    【解决方案2】:

    Pandas 不支持 time dtype 系列

    Pandas(和 NumPy)没有 time dtype。由于您希望避免使用 Pandas timedelta,因此您有 3 个选项:Pandas datetime、Python datetime.time 或 Python str。下面按优先顺序介绍它们。假设您从以下数据框开始:

    df = pd.DataFrame({'time': pd.to_timedelta(['12:34:56', '05:12:45', '15:15:06'])})
    
    print(df['time'].dtype)  # timedelta64[ns]
    

    熊猫datetime系列

    您可以使用 Pandas datetime 系列并包含任意日期组件,例如今天的日期。这样一个系列的基础是整数,这使得这个解决方案最有效和适应性强。

    默认日期(如果未指定)为 1970 年 1 月 1 日:

    df['time'] = pd.to_datetime(df['time'])
    
    print(df)
    
    #                  time
    # 0 1970-01-01 12:34:56
    # 1 1970-01-01 05:12:45
    # 2 1970-01-01 15:15:06
    

    您还可以指定日期,例如今天:

    df['time'] = pd.Timestamp('today').normalize() + df['time']
    
    print(df)
    
    #                  time
    # 0 2019-01-02 12:34:56
    # 1 2019-01-02 05:12:45
    # 2 2019-01-02 15:15:06
    

    Pandas object 系列 Python datetime.time

    标准库中的 Python datetime 模块支持 datetime.time 对象。您可以将您的系列转换为 object dtype 系列,其中包含指向 datetime.time 对象序列的指针。操作将不再被矢量化,但每个基础值将在内部由一个数字表示。

    df['time'] = pd.to_datetime(df['time']).dt.time
    
    print(df)
    
    #        time
    # 0  12:34:56
    # 1  05:12:45
    # 2  15:15:06
    
    print(df['time'].dtype)
    # object
    
    print(type(df['time'].at[0]))
    # <class 'datetime.time'>
    

    Pandas object 系列 Python str

    仅建议将转换为字符串用于其他类型不支持的演示目的,例如Pandas datetime 或 Python datetime.time。例如:

    df['time'] = pd.to_datetime(df['time']).dt.strftime('%H:%M:%S')
    
    print(df)
    
    #        time
    # 0  12:34:56
    # 1  05:12:45
    # 2  15:15:06
    
    print(df['time'].dtype)
    # object
    
    print(type(df['time'].at[0]))
    # <class 'str'>
    

    【讨论】:

    • pd.to_datetime(df['time']) 不再适用于 pandas 1.0。
    • 那个页面没有提到时间增量?
    • @jebob,你之前的评论也没有!
    • 无论文档说什么,错误信息都很清楚:TypeError: dtype timedelta64[ns] cannot be converted to datetime64[ns]
    【解决方案3】:
    df['time_of_day'] = pd.to_datetime(df['time_of_day']).apply(lambda x: x.time())
    

    Adapted this code

    【讨论】:

      【解决方案4】:

      找到了解决方案,但我觉得它必须比这更优雅:

      def convert(x):
          return pd.to_datetime(x).strftime('%H:%M:%S')
      
      df['time_of_day'] = df['time_of_day'].apply(convert)
      

      【讨论】:

      • TypeError: &lt;class 'pandas._libs.tslibs.timedeltas.Timedelta'&gt; is not convertible to datetime
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      相关资源
      最近更新 更多