【问题标题】:How to change the datetime format in Pandas如何更改 Pandas 中的日期时间格式
【发布时间】:2016-10-30 06:41:38
【问题描述】:

我的数据框有一个 DOB 列(示例格式 1/1/2016),默认情况下会转换为 Pandas dtype 'object':DOB object

使用df['DOB'] = pd.to_datetime(df['DOB']) 将此转换为日期格式,日期将转换为:2016-01-26,其dtype 为:DOB datetime64[ns]

现在我想将此日期格式转换为01/26/2016 或任何其他通用日期格式。我该怎么做?

无论我尝试什么方法,它总是以2016-01-26 格式显示日期。

【问题讨论】:

  • 您是否正在寻找仅适用于 Jupyter notebook 的解决方案? (在这种情况下使用每列的“样式器”)还是在普通的 Python 控制台和 iPython 中工作?
  • 注意:datetime 作为保存日期和时间信息的数据结构没有格式 - 它只是一个数据结构。它的内容可以以某种方式/“格式”显示。或者,如果您有代表日期/时间的字符串,则可以在其中以某种方式/“格式”表示。
  • @MrFuppes 确实如此,但它确实具有__str__() 方法的默认格式。我只是提一下,以防任何新手感到困惑。

标签: python string pandas datetime strftime


【解决方案1】:

如果您需要将datetime转换为其他格式,您可以使用dt.strftime(但请注意,然后列的dtype将是objectstring)):

import pandas as pd

df = pd.DataFrame({'DOB': {0: '26/1/2016', 1: '26/1/2016'}})
print (df)
         DOB
0  26/1/2016 
1  26/1/2016

df['DOB'] = pd.to_datetime(df.DOB)
print (df)
         DOB
0 2016-01-26
1 2016-01-26

df['DOB1'] = df['DOB'].dt.strftime('%m/%d/%Y')
print (df)
         DOB        DOB1
0 2016-01-26  01/26/2016
1 2016-01-26  01/26/2016

【讨论】:

  • 'strftime' 将日期时间列转换为 unicode,以便在 DOB1 上应用操作,我们再次必须将其转换为日期时间。就没有其他不丢失data_type的格式化方式吗?
【解决方案2】:

改变格式但不改变类型:

df['date'] = pd.to_datetime(df["date"].dt.strftime('%Y-%m'))

【讨论】:

  • 在你这样做之前记住 df["date"] 应该是 datetime64
  • 否! 假设date 列中某项的原始值为“November 26, 2019”。 strftime() 表示 “来自时间的字符串”,因此 df["date"].dt.strftime('%Y-%m') 将是该项目的 字符串 "2019-11"。然后,pd.to_datetime() 会将这个字符串 back 转换为 datetime64 格式,但现在是“November 1, 2019”!所以结果会是:没有格式变化,而是日期值本身的变化!
  • @MarianD:您在个人答案上的所有 cmets 都很有用,但是您能否在答案底部的“陷阱/不要做这些”的汇总中总结它们?此外,您需要清楚地说明每个问题的问题是:如果任何输入日期不是预期的格式,则这些日期可能会引发异常,或者会破坏日期。简单地写“不!”到处都没有传达这一点。
【解决方案3】:

有区别

  • 数据框单元格的内容(二进制值)和
  • 它的演示文稿(显示它)为我们人类。

所以问题是:如何在不更改数据/数据类型本身的情况下达到我的数据的适当表示

答案如下:

  • 如果您使用Jupyter notebook 来显示您的数据框,或者
  • 如果您想以 HTML 文件 的形式进行演示(即使为进一步 CSS 样式准备了许多多余的idclass 属性-您可以使用也可以不使用它们),

使用 styling样式不会更改数据框列的数据/数据类型。

现在我将向您展示如何在 Jupyter 笔记本中访问它 - 对于 HTML 文件形式的演示文稿,请参阅问题末尾附近的注释。

我会假设您的专栏DOB 已经有datetime64 类型(您表明您知道如何访问它)。我准备了一个简单的数据框(只有一列)来向您展示一些基本样式:

  • 没有样式:

    df
    
          DOB
0  2019-07-03
1  2019-08-03
2  2019-09-03
3  2019-10-03
  • 将其样式化为mm/dd/yyyy:

    df.style.format({"DOB": lambda t: t.strftime("%m/%d/%Y")})
    
          DOB
0  07/03/2019
1  08/03/2019
2  09/03/2019
3  10/03/2019
  • 将其样式化为dd-mm-yyyy:

    df.style.format({"DOB": lambda t: t.strftime("%d-%m-%Y")}) 
    
          DOB
0  03-07-2019
1  03-08-2019
2  03-09-2019
3  03-10-2019

小心!
返回的对象不是数据框——它是Styler 类的对象,所以不要将它分配回df

不要这样做:

df = df.style.format({"DOB": lambda t: t.strftime("%m/%d/%Y")})    # Don't do this!

(每个数据框都有其 Styler 对象,可通过其.style 属性访问,我们更改了此df.style 对象,而不是数据框本身。)


问答:

  • 问: 为什么将您的 Styler 对象(或返回它的表达式)用作 Jupyter 笔记本单元格中的最后一个命令 显示您的(样式化的)表格,而不是 Styler 对象本身?

  • 答:因为每个 Styler 对象都有一个回调方法 ._repr_html_(),它会返回一个 HTML 代码来呈现您的数据框(作为一个漂亮的 HTML 表格)。

    Jupyter Notebook IDE自动调用这个方法来渲染拥有它的对象。


注意:

您不需要 Jupyter 笔记本来设置样式(即,在不更改数据/数据类型的情况下很好地输出数据帧)。

一个 Styler 对象也有一个方法 render(),如果你想获得一个带有 HTML 代码的字符串(例如,将你的格式化数据框发布到 Web,或者只是以 HTML 格式显示你的表格):

df_styler = df.style.format({"DOB": lambda t: t.strftime("%m/%d/%Y")})
HTML_string = df_styler.render()

【讨论】:

  • 值得指出的是,这样的styler代码是专门在Jupyter notebook下运行的,只在Jupyter notebook下生效,在console或iPython中运行绝对零效果 . OP 没有指定“在 Jupyter 下”,因此这可能是也可能不是可行的解决方案,具体取决于他们的设置。许多数据科学代码被复制和粘贴,并且没有明确指定特定于 Jupyter 的假设,然后人们想知道为什么样式器代码在他们的(控制台)环境中运行时“不起作用”。
  • @smci,我的回答的第二段中没有明确提到吗?以条件if 的形式,每个程序员都知道的语句? —尽管感谢您的评论,但它可能对某些人有所帮助。
  • 不,这很不清楚,也被埋没了。最初的问题对 Jupyter 没有任何意义,并且 OP 和一些用户甚至可能没有 Jupyter 可供他们使用。您的答案需要用粗体字写出第一行 “以下方法(样式)仅适用于 Jupyter notebook,并且在 Jupyter notebook 之外运行时将不起作用”。 (在数据科学博客和网站中,我每天都看到有人将 Jupyter 代码发布到非 Jupyter 环境中,并想知道为什么它不起作用)。
  • 酷。我还建议您添加您在其他“convert-to-string-with-strftime-then-back-again-with-pd.to_datetime”方法中发现的所有(许多)陷阱。至少,需要提到引发和捕获异常。此外,pd.to_datetime() 具有参数errors='raise'/'coerce'/'ignore', dayfirst, yearfirst, utc, exact 来控制它的精确度和异常快乐程度,以及无效输出是否被强制转换为NaT 或什么。使“真实世界”数据集中变得更加复杂的是混合/缺失/不完整的格式、时间、时区等;例外不一定是坏事。
  • 有一天会好的。只要你不写“不!”在它下面也是:)
【解决方案4】:

下面的代码对我有用,而不是之前的代码:

df['DOB']=pd.to_datetime(df['DOB'].astype(str), format='%m/%d/%Y')

【讨论】:

  • 否! 您的format='%m/%d/%Y' 参数用于解析字符串,即您应该以这种格式提供字符串(例如"5/13/2019")。 仅此而已,没有格式更改。 它仍将显示为 2019-05-13 — 否则会引发异常,如果 df['DOB'].astype(str) 包含不采用这种格式的项目,例如。 G。格式为"2019-05-13"
  • 什么是“上一个”?它指的是什么帖子?还是您的意思是“以前的”(全部)?请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。
【解决方案5】:

相比the first answer,我会推荐先使用dt.strftime(),再使用pd.to_datetime()。这样,依然会产生datetime数据类型。

例如,

import pandas as pd

df = pd.DataFrame({'DOB': {0: '26/1/2016 ', 1: '26/1/2016 '})
print(df.dtypes)

df['DOB1'] = df['DOB'].dt.strftime('%m/%d/%Y')
print(df.dtypes)

df['DOB1'] = pd.to_datetime(df['DOB1'])
print(df.dtypes)

【讨论】:

  • 这至少在我的情况下不起作用。具体来说,列被转换为日期时间数据类型,但值也被转换为原始格式!
  • 否! 语法错误(缺少大括号),在我的 Pandas (0.25.1) 版本中,另一个语法错误(dt.strftime() — 只能使用 .dt 访问器使用 datetimelike 值)——你依赖于固有的数据类型,但在不同版本的 Pandas 中,固有的数据类型可能不同),还有一个奇怪的逻辑——为什么要将 datetime 转换为 string 然后再转换回 datetime ?请参阅我对 rishi jain 的回答的评论。
【解决方案6】:

你可以试试这个。它将日期格式转换为 DD-MM-YYYY:

df['DOB'] = pd.to_datetime(df['DOB'], dayfirst = True)

【讨论】:

  • No! dayfirst=True 只是日期解析顺序的规范,例如作为“2-1-2019”的矛盾日期字符串将被解析为 2019 年 1 月 2 日,而不是 2019 年 2 月 1 日。仅此而已,输出格式没有变化
【解决方案7】:

以下代码更改为 'datetime' 类型,并以给定的格式字符串格式化。

df['DOB'] = pd.to_datetime(df['DOB'].dt.strftime('%m/%d/%Y'))

【讨论】:

  • 改成这样:df['DOB']=pd.to_datetime(df['DOB']).dt.strftime('%m/%d/%Y')
  • 否! - 为什么要将日期时间转换为字符串,然后再转换回日期时间?查看我的 cmets 以获取其他答案。
【解决方案8】:

以下是对我有用的代码。我们需要非常小心格式。以下链接对于了解您的现有格式并更改为所需格式绝对有用(遵循 strftime() and strptime() Behavior 中的 strftime() 和 strptime() 格式代码):

data['date_new_format'] = pd.to_datetime(data['date_to_be_changed'] , format='%b-%y')

【讨论】:

  • 另一个困惑的人和被误导的答案。请阅读 cmets 到其他答案,它们可能会帮助您理解这一点。
  • 提供的链接将有助于理解各种日期格式及其在 python 中的用法。在没有答案的情况下,我找到了这个。所以我发布它是为了他人的利益。我不认为这里有任何混淆。请具体说明您的 cmets。这样我就可以计划改变我的答案。
  • 我已阅读所有答案和 cmets。它们绝对有用。但除此之外,提供的链接可以更好地理解不同类型的日期格式和对话(*尽可能)
  • 您的回答也很有用。但有用不等于正确答案。例如 “Use deque for FIFO” 也很有用,但与 OP 问题无关。
猜你喜欢
  • 2019-05-01
  • 2018-03-27
  • 1970-01-01
  • 2022-06-12
  • 2015-12-27
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
相关资源
最近更新 更多