パンダの日時形式を変更する方法


109

私のデータフレームには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ノートブックでのみ機能するソリューションをお探しですか?(その場合、列ごとの「スタイラー」を使用します)またはプレーンなPythonコンソールとiPythonで動作しますか?
smci

回答:


206

他の形式dt.strftimeに変換datetimeする必要がある場合に使用できます(ただし、その場合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

32
'strftime'は、DOB1で操作を適用するためにdatetime列をUnicodeに変換します。これを再びdatetimeに変換する必要があります。data_typeを失うことなくフォーマットする他の方法はありませんか?
M.Zaman 2017年

@jezrael、データ型も保持し、日付をオブジェクト列に返さないより良い解決策はありますか?問題は、「df ['DOB1'] = df ['DOB']。dt.strftime( '%m /%d /%Y')」という行の後に変換しようとすると、ソリューションで提案されていることです上記の場合、日付は元の形式に戻ります。
追放

はは、この列を.merge別のデータフレームの日時列に使用したい場合はどうすればよいですか?他の日時列をオブジェクト列に変換して.merge
追放

はいどうやら私は同意するが、「存在しない:(」あなたは私がその新しいフォーマットを失うことなく、そのフォーマットを変更した後のdatetimeに列を変換できないことを私に言ったそうすることによって。?
追放

わかりました、私が理解している限り.merge、両方の列が正確に同じ形式でなくても、両方の列がdatetime列である場合でも、正しく実行できます。これは正解?
追放

21

フォーマットを変更するがタイプは変更しない:

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

ちょうどあなたがこれを行う前に、そのDF [「日付」]はdatetime64する必要があります覚えている
adhg

4
番号!date列の一部のアイテムの元の値が「2019年11月26日」であるとします。strftime()手段「時間から文字列は」、そう df["date"].dt.strftime('%Y-%m')なります文字列 "2019-11"、その項目の。次に、pd.to_datetime()この文字列をフォーマットに戻しdatetime64ますが、現在は「2019年11月1日」になります。したがって、結果は次のようになります。フォーマットは変更されませんが、日付値自体が変更されます。
MarianD

2
@MarianD:個々の回答に関するすべてのコメントは役に立ちますが、回答の下部にある「落とし穴/これらを行わない」の1つのロールアップにまとめてください。また、これらのそれぞれの問題が何であるかを明確に示す必要があります。入力された日付のいずれかが予期された形式でない場合、例外がスローされるか、日付が破損する可能性があります。単に「いいえ」と書くだけです。どこでもそれを伝えていません。
smci

8

以下のコードは前のものの代わりに私のために働きました-それを試してください!

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

2
番号! あなたのformat='%m/%d/%Y'パラメータがあるために解析する、文字列をあなたが想定している。すなわち、このような形式の文字列を提供するために、(例えば"5/13/2019")。それ以上、フォーマットの変更はありません。それは引き続きとして表示されます2019-05-13—またはdf['DOB'].astype(str)、そのような形式ではないアイテム(たとえば、形式)が含まれている場合は、例外が発生します"2019-05-13"
MarianD

4

最初の回答と比較して、最初に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)

2
これは少なくとも私の場合は機能しません。具体的には、列は日時データ型に変換されますが、値も元の形式に変換されます。
追放

番号!構文エラー(括弧がない)、私のバージョンのPandas(0.25.1)では別の構文エラー(dt.strftime()— datetimelike値を持つ.dtアクセサーのみを使用できます)-固有のデータ型に依存していますが、バージョンが異なりますパンダ固有のデータ型は異なる場合があります)、および奇妙なロジック- なぜ日時を文字列に変換してから日時に戻すのですか?rishi jainの回答に対する私のコメントを参照してください。
MarianD

2

違いがあります

  • コンテンツデータフレームセルの(バイナリ値)と
  • そのプレゼンテーションは、私たちのために人間を(それを表示します)。

だから問題は:データ/データ型自体を変更せずに、私のデータの適切なプレゼンテーションに到達する方法は?

ここに答えがあります:

  • データフレームの表示にJupyterノートブックを使用する場合、または
  • HTMLファイルの形式でプレゼンテーションに到達したい場合(さらに CSSスタイルidを設定classするために多くの準備された余分な属性があったとしても、それらを使用してもしなくてもかまいません)。

スタイリングを使用します。スタイリングは、データフレームの列のデータ/データ型を変更しません。

次に、Jupyterノートブックでその方法を説明します。HTMLファイル形式のプレゼンテーションについては、質問の終わり近くにあるメモを参照してください。

私はあなたの列がDOB すでにタイプを持っているdatetime64と仮定します(あなたはあなたがそれに到達する方法を知っていることを示しました)基本的なスタイルを示すために、単純なデータフレーム(1列のみ)を用意しました。

  • スタイルなし:

       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!

(すべてのデータフレームには、その.styleプロパティからアクセス可能なStylerオブジェクトがdf.styleあり、データフレーム自体ではなく、このオブジェクトを変更しました。)


質問と回答:

  • Q: Jupyterノートブックセルの最後のコマンドとして使用されるStylerオブジェクト(またはそれを返す式)が、Stylerオブジェクト自体ではなく、(スタイル付き)テーブルを表示するのはなぜですか?

  • A:すべてのStylerオブジェクトには、._repr_html_()データフレームをレンダリングするためのHTMLコードを返すコールバックメソッドがあります(適切なHTMLテーブルとして)。

    Jupyter Notebook IDEは、このメソッドを自動的に呼び出して、それを含むオブジェクトをレンダリングします。


注意:

スタイリングにJupyterノートブックは必要ありません(つまり、データ/データ型を変更せずにデータフレームを適切に出力するため)。

render()HTMLコードで文字列を取得する場合(たとえば、フォーマットされたデータフレームをWebに公開する場合、または単にHTML形式でテーブルを提示する場合)、Stylerオブジェクトにもmethod があります。

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

このようなスタイラーコードは実行することを意図しており、Jupyter Notebookでのみ有効であり、コンソールまたはiPythonで実行してもまったく効果がないことを指摘しておく価値があります。OPは「アンダージュピター」を指定していなかったため、設定によっては、これが実行可能なソリューションである場合とそうでない場合があります。多くのデータサイエンスコードがコピーアンドペーストされ、Jupyter固有の仮定が明示的に指定されないため、(コンソール)環境でスタイラーコードを実行すると、なぜ「機能しない」のか疑問に思います。
smci

@smci、私の回答の2番目の段落で明示的に言及されていませんか?条件付きの形式でif、すべてのプログラマーにとってステートメントはそれほど有名ですか?—コメントに感謝しますが、一部の人には役立つかもしれません。
MarianD

いいえ、それは非常に不明確で、埋葬されています。元の質問はJupyterについて何も想定していませんでした。OPと一部のユーザーは、Jupyterを使用できない場合もあります。あなたの答えは、最初の行を太字で言う必要があります:「次のアプローチ(スタイリング)はJupyter Notebookでのみ機能し、Jupyter Notebookの外部で実行しても何の影響もありません(私が日常的に目にしているデータサイエンスブログやサイトでは、Jupyterコードを非Jupyter環境に投稿し、なぜそれが機能しないのか疑問に思っています)。
smci

涼しい。また、他の「convert-to-string-with-strftime-then-back-again-with-pd.to_datetime」アプローチで特定したすべての(多くの)落とし穴を追加することをお勧めします。少なくとも、例外の発生とキャッチについて言及する必要があります。また、それがどれほど正確で例外的に満足しているか、無効な出力が強制されるかどうか、または何を強制するかを制御するpd.to_datetime()ための引数があります。「実世界」のデータセットでより複雑になるのは、形式、時刻、タイムゾーンなどが混在する/欠落している/不完全であることです。例外は必ずしも悪いことではありません。errors='raise'/'coerce'/'ignore', dayfirst, yearfirst, utc, exactNaT
smci

...または、Jupyter以外のアプローチにおける落とし穴のロールアップとしてそれを書くことができます。
smci

1

以下のコードは 'datetime'タイプに変更され、指定されたフォーマット文字列にもフォーマットされます。うまくいきます!

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

2
このように変更します。df['DOB']=pd.to_datetime(df['DOB']).dt.strftime('%m/%d/%Y')
ジョン・ドウ

番号!- なぜ日時を文字列に変換してから日時に戻すのですか?他の回答に対する私のコメントを参照してください。
MarianD

1

これを試して、日付形式をDD-MM-YYYYに変換することができます。

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

番号! dayfirst=Trueは、日付解析順序の指定のみです。たとえば、「2-1-2019」としてのあいまいな日付文字列は、2019年2月1日としてではなく、2019年1月2日として解析されます。これ以上、出力フォーマットの変更はありません
MarianD
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.