简体   繁体   English

熊猫数据框列是否可以具有datetime.date类型?

[英]Is it possible for a pandas dataframe column to have datetime.date type?

I am using cx_oracle to fetch date from databases. 我正在使用cx_oracle从数据库中获取日期。 I would like to put the fetched data into a pandas dataframe. 我想将获取的数据放入pandas数据框。 My problem is that the dates are converted to numpy.datetime64 objects which I absolutely don't need. 我的问题是将日期转换为我绝对不需要的numpy.datetime64对象。

I would like to have them as datetime.date objects. 我想将它们作为datetime.date对象。 I have seen the dt.date method but it still gives back numpy datetypes. 我看过dt.date方法,但它仍然返回numpy datetypes。

Edit: It appears that with pandas 0.21.0 or newer, there is no problem holding python datetime.date s in a DataFrame. 编辑:看来,使用熊猫0.21.0或更高版本,在DataFrame中保存python datetime.date没问题。 date-like columns are not automatically converted to datetime64[ns] dtype. 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

For older versions of Pandas: 对于旧版本的Pandas:

There is a way to prevent a Pandas DataFrame from automatically converting datelike values to datetime64[ns] by assigning an additional value such as an empty string which is not datelike to the column. 有一种方法可以防止Pandas DataFrame通过为列分配一个附加值(例如一个不像日期一样的空字符串)来将类似datetime64[ns]值自动转换为datetime64[ns] After the DataFrame is formed, you can remove the non-datelike value: 在形成DataFrame之后,您可以删除非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

Clearly, programming this kind of shenanigan into serious code feels entirely wrong since we're subverting the intent of the developers. 显然,由于我们颠覆了开发人员的意图,因此将这种shenanigan编程为严肃的代码感到完全错误。 There are also computational speed advantages to using datetime64[ns] s over lists or object arrays of datetime.dates . 还有运算速度的优势,使用datetime64[ns]结束了列表或对象阵列datetime.dates Moreover, if df[col] has dtype datetime64[ns] then df[col].dt.date.values returns an object NumPy array of python datetime.date s: 此外,如果df[col]具有dtype datetime64[ns]df[col].dt.date.values返回python datetime.date s的对象NumPy数组:

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)

So you could perhaps enjoy the best of both worlds by keeping the column as datetime64[ns] and using df[col].dt.date.values to obtain datetime.date s when necessary. 因此,您可以通过将列保留为datetime64[ns]并在必要时使用df[col].dt.date.values获得datetime.date来享受两全其美的df[col].dt.date.values

On the other hand, the datetime64[ns] s and Python datetime.date s have different ranges of representable dates. 另一方面, datetime64[ns]和Python datetime.date具有可表示日期的不同范围。

  • datetime64[ns] s can represent datetimes from 1678 AD to 2262 AD . datetime64[ns]可以表示从1678 AD2262 AD日期时间。
  • datetime.date s can represent dates from DT.date(0,1,1) to DT.date(9999,1,1) . datetime.date s可以表示从DT.date(0,1,1)DT.date(9999,1,1)

If the reason why you want to use datetime.date s instead of datetime64[ns] s is to overcome the limited range of representable dates, then perhaps a better alternative is to use a pd.PeriodIndex : 如果要使用datetime.date而不是datetime64[ns]的原因是要克服可表示日期的有限范围,那么也许更好的选择是使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM