如何将 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: <class 'pandas._libs.tslibs.timedeltas.Timedelta'> is not convertible to datetime
以上是关于如何将 timedelta 转换为 pandas 中的时间?的主要内容,如果未能解决你的问题,请参考以下文章
在 Python Pandas DataFrame 中将 timedelta64[ns] 列转换为秒
导出到 excel 时将类“pandas.tslib.Timedelta”转换为字符串