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

时间:2013-04-23 18:50:37

标签: python datetime pandas

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

12 个答案:

答案 0 :(得分:166)

从版本0.15.0开始,现在可以使用.dt轻松完成此操作,只访问日期组件:

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

以上内容会返回datetime.date dtype,如果您想要datetime64,那么您只需normalize时间组件到午夜,这样它就会将所有值设置为{{1} }:

00:00:00

这会将dtype保持为df['normalised_date'] = df['dates'].dt.normalize() ,但显示只显示datetime64值。

答案 1 :(得分:17)

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

A better performing alternative将使用df['dates'].dt.floor('d')。严格来说,它不会只保留日期部分",因为它只是将时间设置为00:00:00。但它确实可以通过OP工作,例如:

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

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

编辑:事实上,OP首选的答案可能是"最新版本的pandas 写csv的时间,如果所有观察结果都是00:00:00并且#34;。

答案 2 :(得分:14)

Pandas DatetimeIndexSeries有一个名为normalize的方法,可以完全按照您的意愿行事。

您可以在this answer中了解更多相关信息。

可以用作ser.dt.normalize()

答案 3 :(得分:5)

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

import pandas as pd

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

答案 4 :(得分:5)

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

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

由于您担心的是写入CSV时的格式,因此只需使用date_format的{​​{1}}参数。例如:

to_csv

有关格式约定,请参见Python's strftime directives

答案 5 :(得分:3)

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

答案 6 :(得分:3)

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

答案 7 :(得分:1)

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()

答案 8 :(得分:0)

简单解决方案:

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

答案 9 :(得分:0)

只是提供最新的答案,以防有人看到此旧帖子。

在转换为日期时间时添加“ utc = False”将删除时区部分,并仅将日期保留为datetime64 [ns]数据类型。

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

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

enter image description here

答案 10 :(得分:0)

这对我来说是UTC时间戳(2020-08-19T09:12:57.945888)

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

答案 11 :(得分:0)

在> 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()更糟。两者都具有进一步的缺点,因为结果不支持datetime.date类型,因此结果无法保存到hdf存储中。

请注意,这里我已使用索引作为日期源;如果您的来源是另一列,则需要添加.dt,例如df.mycol.dt.floor('d')