【发布时间】:2022-11-25 13:55:10
【问题描述】:
我的 Python 代码库中常见的错误来源是日期。
具体来说,日期和日期时间的不同实现,以及如何处理它们之间的比较。
这些是我的代码库中的日期类型
import datetime
import pandas as pd
import polars as pl
x1 = pd.to_datetime('2020-10-01')
x2 = datetime.datetime(2020, 10,1)
x3 = pl.DataFrame({'i':[x2]}).select(pl.col('i').cast(pl.Date)).to_numpy()[0,0]
x4 = pl.DataFrame({'i':[x2]}).select(pl.col('i').cast(pl.Datetime)).to_numpy()[0,0]
x5 = pendulum.parse('2020-10-01')
x6 = x5.date()
x7 = x1.date()
您可以打印它们以查看:
x1=2020-10-01 00:00:00 , type(x1)=<class 'pandas._libs.tslibs.timestamps.Timestamp'>
x2=2020-10-01 00:00:00 , type(x2)=<class 'datetime.datetime'>
x3=2020-10-01 , type(x3)=<class 'numpy.datetime64'>
x4=2020-10-01T00:00:00.000000 , type(x4)=<class 'numpy.datetime64'>
x5=2020-10-01T00:00:00+00:00 , type(x5)=<class 'pendulum.datetime.DateTime'>
x6=2020-10-01 , type(x6)=<class 'pendulum.date.Date'>
x7=2020-10-01 , type(x7)=<class 'datetime.date'>
Python 中是否有规范的日期表示?我想 x7: datetime.date 可能是最接近的......
此外,注意比较是一场噩梦,请参阅此处的表格,尝试执行 xi == xj
| x1 | x2 | x3 | x4 | x5 | x6 | x7 | |
|---|---|---|---|---|---|---|---|
| x1: <class 'pandas._libs.tslibs.timestamps.Timestamp'> | True | True | ERROR: Only resolutions 's', 'ms', 'us', 'ns' are supported. | True | False | True | True |
| x2: <class 'datetime.datetime'> | True | True | False | True | False | False | False |
| x3: <class 'numpy.datetime64'> | True | False | True | True | False | True | True |
| x4: <class 'numpy.datetime64'> | True | True | True | True | False | False | False |
| x5: <class 'pendulum.datetime.DateTime'> | False | False | False | False | True | False | False |
| x6: <class 'pendulum.date.Date'> | True | True | True | False | False | True | True |
| x7: <class 'datetime.date'> | True | False | True | False | False | True | True |
另请注意,它甚至不是对称的:
痛苦在于比较更加陌生。这里是 xi>=xj:
红色代表ERROR:
正如您可以想象的那样,有越来越多的胶水代码来控制它。关于如何在 Python 中处理日期和日期时间类型有什么建议吗?
为简单起见:
- 我从不需要时区数据,一切都应该始终是 UTC
- 有时为了方便起见,日期会作为字符串传递(例如,从 JSON 解析)
- 我最多需要几秒的分辨率,但我 99% 的工作只使用日期。
【问题讨论】:
-
不要写胶水代码;编写一个将各种时间格式转换为规范形式的函数,并在需要比较两个值时始终调用它。更进一步,编写一个
cmp_time函数,它接受两个时间值并为您完成。 -
我尽可能使用
datetime.date和datetime.datetime(即在非数字运算代码中); andpd.Timestamp/np.datetime64我必须的地方(高性能数字代码)。 -
@金德尔;谢谢 - 这就是我所做的,但我必须在几乎所有地方添加这个“to_date”,此时它是我应用程序运行时间的 ~4%(我在大表上工作)。谢谢@Grisha,我将对 np.datetime64 进行基准测试,因为我通常使用数百万行表。
-
我会接受将所有上述类型转换为 np.datetime64 的解决方案 :)
标签: python pandas numpy date datetime