2017-09-04 12 views
0

データベースから日付をフェッチするのにcx_oracleを使用しています。取り込んだデータをpandasデータフレームに入れたいと思います。私の問題は、日付が絶対に必要のないnumpy.datetime64オブジェクトに変換されるということです。pandasデータフレーム列にdatetime.dateタイプを使用することはできますか?

私はdatetime.dateオブジェクトとしてそれらを持っていたいと思います。私はdt.dateメソッドを見ましたが、それでもnumpyのデータ型を返します。

答えて

4

編集:パンダ0.21.0以降では、Python datetime.dateをDataFrameに保持しても問題はありません。 date-like列は自動的にdatetime64[ns]dtypeに変換されません。パンダの古いバージョンの

import numpy as np 
import pandas as pd 
import datetime as DT 

print(pd.__version__) 
# 0.21.0.dev+25.g50e95e0 
dates = [DT.date(2017,1,1)+DT.timedelta(days=2*i) for i in range(3)] 
df = pd.DataFrame({'dates': dates, 'foo': np.arange(len(dates))}) 
print(all([isinstance(item, DT.date) for item in df['dates']])) 
# True 
df['dates'] = (df['dates'] + pd.Timedelta(days=1)) 
print(all([isinstance(item, DT.date) for item in df['dates']])) 
# True 

自動的にそのような 空文字列として付加価値を割り当てることによってdatetime64[ns]に datelike値を変換からパンダデータフレームを防止するための方法が存在しています列にはのようなものではありません。データフレームが形成され したら、非datelike値削除することができます深刻なコードにshenaniganこの種のプログラミング、明らかに

import pandas as pd 
import datetime as DT 
dates = [DT.date(2017,1,1)+DT.timedelta(days=i) for i in range(10)] 
df = pd.DataFrame({'dates':['']+dates}) 
df = df.iloc[1:] 
print(all([isinstance(item, DT.date) for item in df['dates']])) 
# True 

を、我々は、開発者の意図を覆すしているので、完全に間違って感じています。 datetime64[ns]のリストまたはオブジェクト配列の上にdatetime.datesを使用することによる計算速度の利点もあります。 df[col]はその後、DTYPE datetime64[ns]df[col].dt.date.valuesを持っている場合 はまた、パイソンのオブジェクトnumpyの配列datetime.date秒を返します。

import pandas as pd 
import datetime as DT 
dates = [DT.datetime(2017,1,1)+DT.timedelta(days=2*i) for i in range(3)] 
df = pd.DataFrame({'dates': dates}) 
print(repr(df['dates'].dt.date.values)) 
# array([datetime.date(2017, 1, 1), datetime.date(2017, 1, 3), 
#  datetime.date(2017, 1, 5)], dtype=object) 

だから、あなたはおそらくdatetime64[ns]として列を保ち、datetime.date Sを得ることがdf[col].dt.date.valuesを使用して、両方の世界の最高を楽しむことができます必要に応じて

一方、datetime64[ns]とPython datetime.dateの表現可能な範囲の範囲は異なります。

  • datetime64[ns]は、1678 AD to 2262 ADのdatetimesを表すことができます。
  • datetime.dateは、DT.date(0,1,1)からDT.date(9999,1,1)までの日付を表すことができます。

あなたはdatetime.dateではなくdatetime64[ns]秒のS-使用したい理由は、おそらく、その後、表現可能な日数の制限された範囲を克服するためにa better alternative is to use a pd.PeriodIndexある場合:

import pandas as pd 
import datetime as DT 
dates = [DT.date(2017,1,1)+DT.timedelta(days=2*i) for i in range(10)] 
df = pd.DataFrame({'dates':pd.PeriodIndex(dates, freq='D')}) 
print(df) 
#  dates 
# 0 2017-01-01 
# 1 2017-01-03 
# 2 2017-01-05 
# 3 2017-01-07 
# 4 2017-01-09 
# 5 2017-01-11 
# 6 2017-01-13 
# 7 2017-01-15 
# 8 2017-01-17 
# 9 2017-01-19 
関連する問題