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

我使用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是否支持精度规范,以便在处理日常数据时可以摆脱时间部分?

697599 次浏览

转换为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)])

从版本0.15.0开始,现在可以很容易地使用.dt来访问date组件:

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

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

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

这将dtype保留为datetime64,但显示只显示date值。

熊猫DatetimeIndexSeries有一个叫做normalize的方法,它做的正是你想要的。

你可以在这个答案中阅读更多关于它的信息。

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

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

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

  • 印刷到丝网
  • 保存到CSV
  • 使用列groupby

... 而且效率更高,因为运算是向量化的。

编辑:实际上,OP更喜欢的答案可能是“最近版本的pandas写时间到csv,如果它是00:00:00的所有观察”。

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

import pandas as pd


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

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

尽可能避免将你的datetime64[ns]系列转换为datetime.date对象的object dtype系列。后者通常使用pd.Series.dt.date构造,存储为指针数组,相对于纯基于numpy的序列效率较低。

由于您关心的是格式时写入CSV,只需使用to_csvdate_format参数。例如:

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

格式约定参见Python的strftime指令

简单的解决方案:

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

只是给一个最新的答案,以防有人看到这篇旧帖子。

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

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

你将能够在excel中保存它而不会得到错误“ValueError: excel不支持带时区的日期时间。在写入Excel之前,请确保日期时间不受时区影响。”

enter image description here

我希望能够更改数据帧中一组列的类型,然后删除保持日期的时间。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'))

这在UTC时间戳上为我工作(2020-08-19T09:12:57.945888)

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

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

df['Column'] = df['Column'].dt.strftime('%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()