我正在使用cx_oracle从数据库中获取日期。我想将提取的数据放入熊猫数据框中。我的问题是,日期转换为numpy.datetime64
对象,我绝对不需要。pandas dataframe列可能有datetime.date类型吗?
我想将它们作为datetime.date对象。我已经看到了dt.date
方法,但它仍然返回numpy日期类型。
我正在使用cx_oracle从数据库中获取日期。我想将提取的数据放入熊猫数据框中。我的问题是,日期转换为numpy.datetime64
对象,我绝对不需要。pandas dataframe列可能有datetime.date类型吗?
我想将它们作为datetime.date对象。我已经看到了dt.date
方法,但它仍然返回numpy日期类型。
编辑:看来,对于熊猫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