使用 pandas.to_datetime 时只保留日期部分

问题描述 投票:0回答:13

我使用

pandas.to_datetime
来解析我的数据中的日期。 Pandas 默认情况下用
datetime64[ns]
表示日期,即使这些日期都是每日的。 我想知道是否有一种优雅/聪明的方法将日期转换为
datetime.date
datetime64[D]
这样,当我将数据写入 CSV 时,日期不会附加
00:00:00
。我知道我可以逐个元素手动转换类型:

[dt.to_datetime().date() for dt in df.dates]

但这真的很慢,因为我有很多行,这有点违背了使用

pandas.to_datetime
的目的。有没有办法一次性转换整列的
dtype
?或者,
pandas.to_datetime
是否支持精度规范,以便我可以在处理日常数据时摆脱时间部分?

python pandas csv datetime series
13个回答
570
投票

自版本

0.15.0
现在可以使用
.dt
仅访问日期组件轻松完成:

df['just_date'] = df['dates'].dt.date

以上返回

datetime.date
,所以
object
dtype。如果您想将 dtype 保持为
datetime64
,那么您只需
normalize

df['normalised_date'] = df['dates'].dt.normalize()

这将时间组件设置为午夜,即

00:00:00
,但显示屏仅显示日期值。


86
投票

简单的解决方案:

df['date_only'] = df['date_time_column'].dt.date

37
投票

虽然我赞成 EdChum 的回答,这是对 OP 提出的问题最直接的回答,但它并没有真正解决性能问题(它仍然依赖于 python

datetime
对象,因此对它们的任何操作都不会矢量化 - 也就是说,它会很慢)。

更好的替代方案是:

df['dates'].dt.floor('d')

严格来说,它不会“只保留日期部分”,因为它只是将时间设置为

00:00:00
。但它确实按照 OP 的要求工作,例如:

  • 打印到屏幕
  • 保存到 csv
  • 使用专栏
    groupby

...而且效率更高,因为操作是矢量化的。

编辑: 事实上,OP 更喜欢的答案可能是“

pandas
的最新版本做not 如果它是所有观察的
00:00:00
,则将时间写入 csv”。


22
投票

Pandas v0.13+:使用
to_csv
date_format
参数

尽可能避免将

datetime64[ns]
系列转换为
object
dtype 系列的
datetime.date
对象。后者通常使用
pd.Series.dt.date
构造,存储为指针数组,相对于纯基于 NumPy 的系列而言效率低下。

由于您关心的是写入CSV时的格式,因此只需使用

date_format
to_csv
参数即可。例如:

df.to_csv(filename, date_format='%Y-%m-%d')

参见Python的

strftime
指令格式约定。


20
投票

这是提取日期的简单方法:

import pandas as pd

d='2015-01-08 22:44:09' 
date=pd.to_datetime(d).date()
print(date)

20
投票

Pandas

DatetimeIndex
Series
有一个名为
normalize
的方法,它完全可以满足您的需求。

您可以在this answer中阅读更多相关信息。

它可以用作

ser.dt.normalize()


15
投票

如果有人看到这篇旧帖子,请提供更新的答案。

在转换为 datetime 时添加“utc=False”将删除时区组件并仅保留 datetime64[ns] 数据类型中的日期。

pd.to_datetime(df['Date'], utc=False)

您将能够将其保存在 excel 中而不会出现错误“ValueError:Excel 不支持带时区的日期时间。请确保在写入 Excel 之前不知道日期时间是时区。”


14
投票
df['Column'] = df['Column'].dt.strftime('%m/%d/%Y')

这将为您提供所需格式的日期和 NO TIME。您可以根据需要更改格式

'%m/%d/%Y'
。它将列的数据类型更改为
'object'
.


如果您只想要日期而不想要

YYYY-MM-DD
格式的时间,请使用:

df['Column'] = pd.to_datetime(df['Column']).dt.date

数据类型将为

'object'
.


对于

'datetime64'
数据类型,使用:

df['Column'] = pd.to_datetime(df['Column']).dt.normalize()

6
投票

转换为

datetime64[D]

df.dates.values.astype('M8[D]')

尽管将其重新分配给 DataFrame col 会将其恢复为 [ns]。

如果你想要实际的

datetime.date

dt = pd.DatetimeIndex(df.dates)
dates = np.array([datetime.date(*date_tuple) for date_tuple in zip(dt.year, dt.month, dt.day)])

5
投票

我希望能够更改数据框中一组列的类型,然后删除保留日期的时间。 round(), floor(), ceil() 所有的工作

df[date_columns] = df[date_columns].apply(pd.to_datetime)
df[date_columns] = df[date_columns].apply(lambda t: t.dt.floor('d'))

4
投票

在超过 1000000 行的表上,我发现它们都很快,

floor
只是稍微快一点:

df['mydate'] = df.index.floor('d')

df['mydate'] = df.index.normalize()

如果您的索引有时区并且您不想在结果中出现这些时区,请执行以下操作:

df['mydate'] = df.index.tz_localize(None).floor('d')

df.index.date
慢很多倍;
to_datetime()
更糟。两者都有进一步的缺点,即结果无法保存到 hdf 存储中,因为它不支持类型 datetime.date。

请注意,我在这里使用索引作为日期来源;如果您的来源是另一列,则需要添加

.dt
,例如
df.mycol.dt.floor('d')


1
投票

这对我有用 UTC 时间戳 (2020-08-19T09:12:57.945888)

for di, i in enumerate(df['YourColumnName']):
    df['YourColumnName'][di] = pd.Timestamp(i)

0
投票

如果该列尚未采用日期时间格式:

df['DTformat'] = pd.to_datetime(df['col'])

一旦采用日期时间格式,您就可以像这样将整个列转换为日期:

df['DateOnly'] = df['DTformat'].apply(lambda x: x.date())
© www.soinside.com 2019 - 2024. All rights reserved.