2017-09-04 71 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 
相关问题