落入datetime.date 和 numpy.datetime64 的使用大坑

落入datetime.date 和 numpy.datetime64 的使用大坑

1. 不同模块日期的问题

数据加载模块和数据处理模块合并联调,发现落入datetime.date 和 numpy.datetime64 / pandas.Timestamp 的使用大坑 。
数据加载模块独立测试没有问题,数据处理模块独立测试没有问题。两者联调,问题不断,总体看就是从数据库加载到dataframe中,日期类型不一致,修改好一处错误,其他地方再出新错误,四处报错。
使用日期的地方,格式不统一,模块中都有各自日期格式转换,修改一处,另外的地方就出错 。
一系列错误:

TypeError: '>=' not supported between instances of 'datetime.date' and 'str'

TypeError: Expect data.index as DatetimeIndex

TypeError: input must have type NumPy datetime

AttributeError: 'numpy.datetime64' object has no attribute 'strftime'

重新梳理 datetime.date / numpy.datetime64 / pandas.Timestamp 的关系和区别 ,不同格式之间日期转换。

2. numpy.datetime64和datetime.date

在Python中,numpy.datetime64和datetime.date都用于表示日期,但它们属于不同的库,并且在使用上存在一些关键的区别。

(1)区别

库来源:
numpy.datetime64是NumPy库提供的数据类型,专门用于数组中的日期和时间数据。
datetime.date是Python标准库datetime模块中的一个类,用于表示日期(年、月、日)。

(2)功能

numpy.datetime64提供了丰富的日期和时间操作,并且非常适合在大型数组或矩阵中进行高效的数值计算。
datetime.date提供了更多的日期处理功能,比如格式化输出、与其他日期时间对象进行比较等。

(3)存储

numpy.datetime64在NumPy数组中是以一种紧凑的格式存储的,这有助于节省内存和提高计算效率。
datetime.date对象通常占用更多的内存,因为它们包含更多的方法和属性。
数组支持:
numpy.datetime64特别适用于NumPy数组,可以直接在数组上进行日期和时间的计算。
datetime.date对象不能直接存储在NumPy数组中,除非将其转换为object类型,这通常会降低计算效率。

(4)转换

将numpy.datetime64转换为datetime.date:
使用numpy.datetime64对象的.astype(object)方法将其转换为Python对象,然后使用datetime.date构造函数进行转换。

  • datetime64 转date :
import numpy as np  
from datetime import date  
 
# 创建一个numpy.datetime64对象  
np_date = np.datetime64('2023-01-01')  
 
# 转换为datetime.date对象  
dt_date = date(np_date.astype('O').year, np_date.astype('O').month, np_date.astype('O').day)
print(dt_date,type(dt_date))

结果:

2023-01-01 <class ‘datetime.date’>

  • date 转 datetime64 :
import numpy as np  
from datetime import date  
 
# 创建一个datetime.date对象  
dt_date = date(2023, 1, 1)  
 
# 转换为numpy.datetime64对象  
np_date = np.datetime64(dt_date)
print(np_date,type(np_date))

结果:

2023-01-01 <class ‘numpy.datetime64’>

(5)注意事项

当将numpy.datetime64对象转换为datetime.date对象时,注意numpy.datetime64对象可能包含时间信息,这部分信息在转换到datetime.date时会丢失。
如果numpy.datetime64对象包含时区信息,转换到datetime.date时也需要特别处理时区转换。
在实际应用中,选择使用哪种类型取决于具体需求。如果在处理大型数组并且需要高效的数值计算,numpy.datetime64可能是更好的选择。如果需要更多的日期处理功能,比如字符串格式化或与其他日期时间对象的比较,那么datetime.date可能更合适。

(6)datetime64 日期加减

在NumPy中,np.datetime64日期类型可以通过简单的算术运算来增加或减少天数。这是因为np.datetime64对象支持时间单位(如’D’表示天)的算术运算。

参数
np.timedelta64 的参数主要包括两部分:

单位数:一个整数或浮点数,表示时间单位的数量。
时间单位:一个字符串,表示时间单位,‘W’ 表示周, ‘D’ 表示天,‘h’ 表示小时,‘m’ 表示分钟,‘s’ 表示秒。

import numpy as np  
  
# 创建一个np.datetime64日期  
date = np.datetime64('2023-01-01')  
  
# 加一天  
date_plus_one_day = date + np.timedelta64(1, 'D')  
print(date_plus_one_day)  # 输出:2023-01-02  
  
# 减一天  
date_minus_one_day = date - np.timedelta64(1, 'D')  
print(date_minus_one_day)  # 输出:2022-12-31

# 加一周  
date_plus_one_day = date + np.timedelta64(1, 'W')  
print(date_plus_one_day)  # 输出:2023-01-08
  
# 减一周  
date_minus_one_day = date - np.timedelta64(1, 'W')  
print(date_minus_one_day)  # 输出:2022-12-25


增加一个月、年,需要用pd.Timestamp

import pandas as pd  
import numpy as np  
  
# 创建一个 datetime64 对象表示某个日期  
date = np.datetime64('2024-01-01')  
  
# 将 numpy 的 datetime64 转换为 pandas 的 Timestamp  
timestamp = pd.Timestamp(date)  
  
# 使用 pandas 添加一个月  
new_date_plus_month = timestamp + pd.DateOffset(months=1)  
  
# 使用 pandas 添加一年  
new_date_plus_year = timestamp + pd.DateOffset(years=1)  
  
# 将 pandas 的 Timestamp 转换回 numpy 的 datetime64(如果需要)  
new_date_plus_month_np = new_date_plus_month.to_datetime64()  
new_date_plus_year_np = new_date_plus_year.to_datetime64()  
  
print(new_date_plus_month_np)  # 输出添加一个月后的日期  
print(new_date_plus_year_np)   # 输出添加一年后的日期

结果:

2024-02-01T00:00:00
2025-01-01T00:00:00

3.pandas.Timestamp和numpy.datetime64

pandas.Timestamp和numpy.datetime64都是用于表示日期和时间的类型,但它们来自不同的库(Pandas和NumPy),并且在功能和使用上存在一些重要的区别。

(1)pandas.Timestamp

pandas.Timestamp是Pandas库中用于表示单个时间点的主要类型。它提供了比numpy.datetime64更丰富的功能集,尤其是在处理时间序列数据时。

  • 特点:

    • 时区支持:pandas.Timestamp可以包含时区信息,这使得处理跨越多个时区的数据变得相对简单。

    • 频率和偏移:它支持日期时间的频率和偏移,如“日”、“月”、“季度”等,使得时间序列的生成和重采样变得容易。

    • 纳秒级精度:默认情况下,pandas.Timestamp提供纳秒级的时间精度。

    • 字符串格式化:pandas.Timestamp对象可以很容易地格式化为各种字符串表示形式,这对于报告和可视化非常有用。

  • 操作:支持与其他pandas.Timestamp对象进行算术运算(如加、减)。

  • 使用:

pandas.Timestamp通常用于Pandas的Series和DataFrame中,尤其是在时间序列分析中。它使得数据的索引、切片、重采样等操作变得简单。

(2)numpy.datetime64

numpy.datetime64是NumPy库中用于表示日期和时间的类型。它主要用于数值计算和科学计算。

  • 特点:

    • 高效性:numpy.datetime64在NumPy数组中的存储和计算是高效的,特别适用于大规模数据的处理。

    • 固定精度:它支持不同的时间单位(如’D’表示天,'s’表示秒等),但一旦数据类型被确定,精度就是固定的。

    • 算术运算:支持与其他numpy.datetime64对象或numpy.timedelta64对象进行算术运算。

    • 兼容性:与Python的内置datetime对象相比,numpy.datetime64更易于在NumPy数组中进行操作。

  • 使用:

numpy.datetime64通常用于需要高效数值计算的场合,特别是在处理包含日期时间数据的NumPy数组时。它也可以与其他NumPy函数和工具无缝集成,用于数据分析和科学计算。

  • 区别与选择
    在选择使用pandas.Timestamp还是numpy.datetime64时,主要取决于具体需求和你正在使用的库。如果处理时间序列数据,特别是使用Pandas进行数据分析时,pandas.Timestamp通常是更好的选择,因为它提供了更丰富的功能集。而如果进行科学计算或需要高效处理大规模日期时间数据时,numpy.datetime64可能更合适。

**注意:**虽然两者在功能上有所不同,但它们在许多情况下可以相互转换。例如,你可以将pandas.Timestamp转换为numpy.datetime64对象,反之亦然。

(3)相互转换

pandas.Timestamp对象和numpy.datetime64对象可以相互转换,因为它们在内部都表示日期和时间信息。以下是它们之间转换的方法:

将pandas.Timestamp转换为numpy.datetime64
可以直接使用pandas.Timestamp对象的.to_datetime64()方法或者简单地将它转换为numpy.datetime64类型。

  • Timestamp 转 datetime64
import pandas as pd  
import numpy as np  
  
# 创建一个pandas.Timestamp对象  
ts = pd.Timestamp('2023-01-01')  
  
# 使用.to_datetime64()方法转换  
np_dt64 = ts.to_datetime64()  
  
# 或者直接转换类型  
np_dt64_direct = np.datetime64(ts)  

print(ts,type(ts))             # 输出:2023-01-01 00:00:00
print(np_dt64,type(np_dt64))        # 输出:2023-01-01T00:00:00
print(np_dt64_direct,type(np_dt64_direct)) # 输出:2023-01-01T00:00:00.000000000

结果:

2023-01-01 00:00:00 <class ‘pandas._libs.tslibs.timestamps.Timestamp’>
2023-01-01T00:00:00 <class ‘numpy.datetime64’>
2023-01-01T00:00:00.000000 <class ‘numpy.datetime64’>

注意:
pd的Timestamp 转换datetime64 ,和 np直接转换datetime64 ,精度不同。

  • datetime64 转 Timestamp
import pandas as pd  
import numpy as np  
  
# 创建一个numpy.datetime64对象  
np_dt64 = np.datetime64('2023-01-01')  
  
# 转换为pandas.Timestamp对象  
ts = pd.Timestamp(np_dt64)  
  
print(ts) # 输出:2023-01-01 00:00:00

结果:

2023-01-01 00:00:00

4.datetime.datetime

datetime.datetime 是 Python 标准库 datetime 模块中的一个类,它提供了丰富的日期和时间操作功能。下面是

(1)datetime.datetime 的主要特点:
  • 日期和时间表示:datetime.datetime 对象可以同时表示日期和时间,包括年、月、日、时、分、秒、微秒。
  • 时区支持:虽然基本的 datetime.datetime 对象不直接支持时区,但可以使用 datetime.timezone 和 datetime.timedelta 类来处理时区相关的计算。
  • 算术运算:datetime.datetime 对象支持加法和减法运算,可以方便地进行日期和时间的偏移。
  • 格式化:可以方便地将 datetime.datetime 对象转换为字符串,也可以将字符串解析为 datetime.datetime 对象。
(2) 日期转换为字符串

要将 datetime.datetime 对象转换为字符串,可以使用 strftime 方法,该方法允许你指定输出的格式。

  • 日期转字符串
import datetime  
  
# 创建一个 datetime 对象  
now = datetime.datetime.now()  
  
# 转换为字符串  
formatted_date = now.strftime('%Y-%m-%d %H:%M:%S')  
print(formatted_date)  # 输出类似于 "2024-03-08 10:39:26" 的字符串

结果:

2024-03-08 10:39:26

(3) 字符串转换为日期
  • 字符串转日期
import datetime  
  
# 字符串表示的日期和时间  
date_str = '2023-03-15 14:30:45'  
  
# 解析字符串为 datetime 对象  
parsed_date = datetime.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')  
print(parsed_date)  # 输出 datetime 对象

结果:

2023-03-15 14:30:45

(4)日期加减
# 创建一个 datetime 对象  
now = datetime.datetime.now()  
  
# 增加一天  
one_day_later = now + datetime.timedelta(days=1)  
print(one_day_later,type(one_day_later))  # 输出一天后的日期和时间

ios_str = one_day_later.isoformat()
print(ios_str,type (ios_str))  # 输出一天后的日期和时间

import datetime  
  
# 创建一个 datetime 对象  
now = datetime.datetime.now()  
  
# 增加一周  
one_week_later = now + datetime.timedelta(weeks=1)  
print(one_week_later)  # 输出一周后的日期和时间
date_week = one_week_later.date()
print(date_week,type(date_week))  # 输出一周后的日期

结果:

2024-03-09 10:46:49.783701 <class ‘datetime.datetime’>
2024-03-09T10:46:49.783701 <class ‘str’>
2024-03-15 10:46:49.784441
2024-03-15 <class ‘datetime.date’>

(5)pandas.Timestamp转换datetime

使用to_pydatetime方法转换datetime 。

ts = pd.Timestamp('2020-05-20 00:00:00', tz=None)
print(type(ts))
print(ts)

print(type(ts.to_pydatetime()))
print(ts.to_pydatetime())

结果:

<class ‘pandas._libs.tslibs.timestamps.Timestamp’>
2020-05-20 00:00:00
<class ‘datetime.datetime’>
2020-05-20 00:00:00

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值