如何将 timedelta 转换为 pandas 中的时间?

Posted

技术标签:

【中文标题】如何将 timedelta 转换为 pandas 中的时间?【英文标题】:How to convert timedelta to time of day in 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 来说是自然的。 【参考方案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,文档另有建议:pandas.pydata.org/pandas-docs/stable/reference/api/… 那个页面没有提到时间增量? @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

以上是关于如何将 timedelta 转换为 pandas 中的时间?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python Pandas DataFrame 中将 timedelta64[ns] 列转换为秒

导出到 excel 时将类“pandas.tslib.Timedelta”转换为字符串

Pandas Timedelta 以天为单位

查询pandas中的timedelta列,过滤行

将 Pandas DatetimeIndex 转换为数字格式

如何将 timedelta 与 pandas df.query() 一起使用?