我需要存储一些超过年份2262限制的日期。由于我只需要日期,不需要时间,所以我认为我可以使用datetime.date
,它确实很好,直到我意识到在代码的后面有一些强制的数据类型,我无法绕过这一点。示例:
import pandas as pd
import datetime
data = pd.DataFrame({"col1": ["2022-12-31", "9999-12-31"]})
data["col2"] = data["col1"].apply(lambda x: datetime.date.fromisoformat(x))
# .... company code ....
# forced coercion
data.astype(dtype={"col1": str, "col2": datetime.date})
除其他外,我试图提供以下类型的col2
强制,但没有成功。
datetime.date
->数据类型'<类'datetime.date'>'不理解np.datetime64
->越界纳秒时间戳:9999-12-31 00:00:00
我还试图用data["col2"].dt.to_pydatetime()
进行转换;只能将.dt访问器与datetime-like值"一起使用;错误
我想最让我困惑的是,astype()
文档说可以提供任何numpy或Python数据类型,我的理解是datetime.date
是Python数据类型。为什么astype()
不知道呢?
是的,你不能提供任何有效的Python类型(我不认为文档会这么说(。我想这意味着你可以提供numpy类型以及Pandas(或其他库(添加的扩展dtypes,在这个表中列出。
在您的情况下,您可能希望使用Period,这是文档中针对这种情况的建议之一。所以它应该是这样的:
def convert_to_date(x):
y, m, d = [int(n) for n in x.split('-')]
return pd.Period(year=y, month=m, day=d, freq="D")
data = pd.DataFrame({"col1": ["2022-12-31", "9999-12-31"]})
data["col2"] = data.col1.apply(convert_to_date)
data.astype(dtype={"col1": str, "col2": 'period[D]'})
通过这种方式,您可以使用矢量化操作(即,它不是像datetime.date
那样的对象数据类型(,但也可以存储Pandadatetime64[ns]
数据类型范围之外的日期。