2017-09-04 102 views
0

我正在使用cx_oracle從數據庫中獲取日期。我想將提取的數據放入熊貓數據框中。我的問題是,日期轉換爲numpy.datetime64對象,我絕對不需要。pandas dataframe列可能有datetime.date類型嗎?

我想將它們作爲datetime.date對象。我已經看到了dt.date方法,但它仍然返回numpy日期類型。

回答

4

編輯:看來,對於熊貓0.21.0或更新的版本,在DataFrame中保存python datetime.date是沒有問題的。 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 

對於舊版本的熊貓:

有一種方法,以防止大熊貓數據幀從通過分配額外的值,例如一個 空字符串自動轉換 datelike值datetime64[ns]其不是日期式的列。數據幀是 形成後,可以刪除非datelike值:

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 

顯然,這種shenanigan的編程陷入嚴重的代碼感覺完全錯誤的,因爲我們顛覆了開發者的意圖。 使用datetime64[ns]優於datetime.dates的列表或對象數組也有計算速度優勢。 此外,如果df[col]具有D型datetime64[ns]然後df[col].dt.date.values返回蟒datetime.date S的對象與NumPy數組:通過保持列datetime64[ns]和使用df[col].dt.date.values獲得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]和Python datetime.date具有不同的可表示日期範圍。

  • datetime64[ns] s可以代表從1678 AD to 2262 AD的日期時間。
  • datetime.date s可以表示從DT.date(0,1,1)DT.date(9999,1,1)的日期。

如果你爲什麼要使用datetime.date的原因S的datetime64[ns]!而非是克服表示的日期的有限範圍內,那麼也許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 
相關問題