pandas.to_datetimeを使用する場合は日付部分のみを保持


201

pandas.to_datetimeデータの日付を解析するために使用します。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、毎日のデータを処理しながら時間の部分を取り除くことができるように、精度仕様をサポートしていますか?


2
良い方法はわかりませんが、df.dates.apply(lambda x: x.date()) 少なくとももう少し速いはずです。github.com/pydata/pandas/issues/2583
rootを


1
私はこれら2つの質問を異なるものと見なします。参照する可能性のある重複は、日時列から日付部分と時間部分を分割することを目的としています。この質問は、列全体を一度に変換することによって動機付けられます。日付を表す20列のデータフレームがあるとします。他の質問で提案されているように、csvに書き込む列を指定する必要はありません。

1
これは現時点ではサポートされていません(@rootは可能な拡張を指します)。csvに書き込むときに、これを行う目的は何ですか?
ジェフ

3
よく、多くの場合、他のプログラムで読み取られるようにcsvファイルにデータを書き込む必要があります。冗長な00:00:00は、特に純粋に毎日のデータで作業している場合は特に、一般的に処理を難しくします。

回答:


286

バージョン以降、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()

これによりdtypeは保持されますdatetime64が、ディスプレイにはdate値のみが表示されます。


33

簡単な解決策:

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

単なる警告です。これにより、タイプがオブジェクトに変更されます。したがって、一貫性を保つためにastype( 'datetime64')を実行する必要があります。
ミサントループ

25

OPが提起した質問に対する最も直接的な回答であるEdChumの回答に賛成しましたが、それは実際にはパフォーマンスの問題を解決しません(それは依然としてpython datetimeオブジェクトに依存しているため、それらに対するすべての操作はベクトル化されません-つまり、遅くなります)。

より良いパフォーマンスの代替策は、を使用することdf['dates'].dt.floor('d')です。厳密に言えば、時刻をに設定するだけなので、「日付部分のみを保持する」ことはありません00:00:00。しかし、たとえば次のような場合には、OPの要求どおりに機能します。

  • スクリーンへの印刷
  • CSVに保存
  • 列を使用して groupby

...そして演算はベクトル化されているので、はるかに効率的です。

編集:実際には、OP年代が望ましいだろう答えはおそらく「の最近のバージョンがあるpandasではないことがある場合は、CSVへの書き込み時間を00:00:00すべての観測のために」。


残念ながらto_jsonまだ完全に書いてい00:00:00ます。
IanS

@IanSとはどういう意味date_format='iso'ですか?デフォルトでは、エポックからの秒数のみを出力します。
Pietro Battiston

はい、そういう意味です。
IanS

これはdt.normalize()、数百要素よりも長いシリーズよりも高速です。
C8H10N4O2 2017

16

パンダDatetimeIndexSeries呼ばれるメソッドがあり、normalizeそれはまさにあなたが望むものを実行します。

詳細については、この回答をご覧ください。

それはとして使用することができます ser.dt.normalize()


15

パンダv0.13 +:使用to_csvしてdate_formatパラメータ

避け、可能な限り、あなたの変換datetime64[ns]にシリーズをobjectのDTYPEシリーズdatetime.dateオブジェクト。後者は、しばしばを使用して構築pd.Series.dt.dateされ、ポインターの配列として格納され、純粋なNumPyベースのシリーズに比べて非効率的です。

CSVに書き込むときの形式が問題なので、のdate_formatパラメーターを使用しますto_csv。例えば:

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

フォーマット規則については、Pythonのstrftimeディレクティブを参照してください。


8

これは日付を抽出する簡単な方法です:

import pandas as pd

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

OPは既に質問で.date()メソッドを使用しているため、この解決策では質問に回答しませんが、参考としてdate()メソッドを使用する簡単な例を確認すると便利です。
Nic Sc​​ozzaro 2018年

5

への変換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)])

3
astype( 'M8 [D]')を使用している場合、欠落している値が元の日付1970-1-1に変換されます。おそらく、最近はpandas.to_datetime()を使用する方が良いでしょう。
Stewbaca

1
datetimeモジュールをとして定期的に含める人には注意してくださいdt。この回答スニペットはそのモジュールを上書きします。@ Dale-Jung、おそらく行をdt_indexのようなものに変更する可能性があります
yeliabsalohcin

また、次にdf.loc[date]メソッドを使用して新しい行を追加しようとすると、インデックスがタイムスタンプに戻り、以降の比較が機能しなくなるという問題も発見しています
yeliabsalohcin

3

誰かがこの古い投稿を見た場合に備えて、最新の回答を提供するだけです。

datetimeに変換するときに「utc = False」を追加すると、タイムゾーンコンポーネントが削除され、datetime64 [ns]データ型の日付のみが保持されます。

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

「ValueError:Excelはタイムゾーンのある日時をサポートしていません。Excelに書き込む前に日時がタイムゾーンに対応していないことを確認してください。」というエラーが発生することなく、Excelに保存できます。

ここに画像の説明を入力してください


列に集計関数を適用した後、これは何らかの理由で失敗します。
RaphX

0

データフレームの一連の列のタイプを変更し、その日の時間を削除できるようにしたいと考えました。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'))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.