333

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

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

但这真的很慢,因为我有很多行,这有点违背了使用pandas.to_datetime. 有没有办法dtype一次转换整个列的?或者,是否pandas.to_datetime支持精度规范,以便我可以在处理日常数据时摆脱时间部分?

4

12 回答 12

501

由于版本0.15.0,现在可以使用.dt仅访问日期组件轻松完成此操作:

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

上面返回一个datetime.datedtype,如果你想要一个,datetime64那么你可以normalize将时间组件设置为午夜,因此它将所有值设置为00:00:00

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

这将保留dtypeas datetime64,但显示仅显示该date值。

于 2015-12-14T22:07:34.700 回答
74

简单的解决方案:

df['date_only'] = df['date_time_column'].dt.date
于 2019-05-20T10:11:16.763 回答
36

虽然我赞成 EdChum 的回答,这是对 OP 提出的问题的最直接回答,但它并没有真正解决性能问题(它仍然依赖于 pythondatetime对象,因此对它们的任何操作都不会被矢量化——也就是说,它会很慢)。

性能更好的替代方法是使用df['dates'].dt.floor('d'). 严格来说,它不是“只保留日期部分”,因为它只是将时间设置为00:00:00. 但它确实可以按照 OP 的要求工作,例如:

  • 打印到屏幕
  • 保存到 csv
  • 使用该列groupby

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

编辑:事实上,OP 更喜欢的答案可能是“如果它用于所有观察,pandas则不要将时间写入 csv 的最新版本”。00:00:00

于 2017-01-18T11:57:38.823 回答
22

Pandas v0.13+:to_csvdate_format参数一起使用

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

由于您在写入 CSV 时关心的是格式,因此只需date_format使用to_csv. 例如:

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

请参阅Python 的格式约定strftime指令

于 2018-12-14T00:19:06.380 回答
20

PandasDatetimeIndexSeries有一个名为的方法normalize,它完全符合您的要求。

您可以在此答案中阅读更多相关信息。

它可以用作ser.dt.normalize()

于 2016-11-02T12:31:05.640 回答
17

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

import pandas as pd

d='2015-01-08 22:44:09' 
date=pd.to_datetime(d).date()
print(date)
于 2017-12-11T12:02:57.960 回答
13

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

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

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

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

在此处输入图像描述

于 2019-11-17T19:16:20.833 回答
7

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()
于 2021-08-05T19:43:49.933 回答
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)])
于 2013-04-23T20:07:12.260 回答
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'))
于 2020-05-04T22:20:58.330 回答
3

在 >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')

于 2020-11-30T13:02:20.323 回答
1

这在 UTC Timestamp (2020-08-19T09:12:57.945888) 上对我有用

for di, i in enumerate(df['YourColumnName']):
    df['YourColumnName'][di] = pd.Timestamp(i)
于 2020-09-08T09:45:10.807 回答