python dataframe日期运算常见的报错及解决方法 - unsupported operand type(s) for -: ‘DatetimeArray‘ and ‘str‘等

1、背景描述:(日期加减计算经常遇到的报错)

数据分析中要对日期进行计算,经常遇到这些报错或问题:

  1. TypeError: cannot subtract DatetimeArray from ndarray
  2. TypeError: unsupported operand type(s) for -: ‘DatetimeArray’ and ‘datetime.date’
  3. TypeError: unsupported operand type(s) for -: ‘DatetimeArray’ and ‘str’

2、问题根本原因及解决方法:

根本原因:两个参与计算的日期类型不一致导致。通常情况是一个类型是datetime.date, 而另一个是timestamps.Timestamp。这样就导致了上述的这些报错信息!
解决方法:

  1. 统一转换为日期类型(datetime.date)来计算
    df[“date”] = df[“date”].map(lambda x: datetime.strptime(x, “%Y.%m.%d”).date())
  2. 统一转换为时间戳(timestamps.Timestamp)的类型来计算;
    df[“date”] = df[“date”].map(lambda x: datetime.strptime(x, “%Y.%m.%d”))
  3. 直接使用pd.to_datetime() 函数来将所有日期转换为时间戳类型来计算

3、问题解决(示例代码 python)

3.1 建立含有日期的数据表(任务:与输入的登录日期“2021/10/15”进行计算)
from datetime import *
# 3.1 建立含日期的数据表
set1 = {"date1": ["2021.09.15", "2021.09.17", "2020.03.20", "2021.01.15", "2020.01.25"],
        "values": [10, 50, 20, 40, 30]}
df = pd.DataFrame(set1, columns=["date1", "values"])

在这里插入图片描述
上述表格中的日期类型是“str", 是不能直接进行计算的,需要进行类型的转换。

3.2 日期类型的转换
#3.2  将数据表中的日期从"str"转换为日期类型
df["date1"] = df["date1"].map(lambda x: datetime.strptime(x, "%Y.%m.%d"))
print("date1的数据类型:", type(df["date1"][1]))
df["date1"]

在这里插入图片描述
一般情况下,将日期转换后通常会认为这个"date1"的类型是日期类型(datetime.date), 但是它实际是日期时间的类型(dtype: datetime64[ns] = “timestamps.Timestamp”),因为很容易被忽视,这就是我们遇到上述报错的根本原因之一!

正确的转换为日期类型(datetime.date)方式为:

# 正确转换为日期类型(datetime.date)的方式:
df["date1"] = df["date1"].map(lambda x: datetime.strptime(x, "%Y.%m.%d").date())
print("date1的数据类型:", type(df["date1"][1]))
df

在这里插入图片描述
了解了问题的根本原因,则正确的解决方法有以下3种:

3.3 解决方法一:统一将日期转换为datetime.date 的日期类型来计算:
# 3.3 方式一:转换为datetime.date的日期类型来计算
df["date1"] = df["date1"].map(lambda x: datetime.strptime(x, "%Y.%m.%d").date())
print("date1的数据类型:", type(df["date1"][1]))
# 输入日期,并计算之间的日期差值
login = "2021.10.15"
login = datetime.strptime(login, "%Y.%m.%d").date()
df["time"] = login - df["date1"]
df

在这里插入图片描述

3.4 解决方法二:统一转换为时间戳(timestamps.Timestamp)的类型来计算:
# 3.4 方式二:转换为timestamps.Timestamp的时间类型来计算
df["date1"] = df["date1"].map(lambda x: datetime.strptime(x, "%Y.%m.%d"))
print("date1的数据类型:", type(df["date1"][1]))
# 输入日期,并计算之间的日期差值
login = "2021.10.15"
login = datetime.strptime(login, "%Y.%m.%d")
df["time"] = login - df["date1"]
df

在这里插入图片描述

3.5 解决方法三:无论原来的日期类型是什么,直接使用pd.to_datetime() 函数来将所有日期转换为时间戳类型来计算
# 3.5 方式三:使用pd.to_datetime()函数来转换所有日期为时间戳类型(timestamps.Timestam)来计算
df["date1"] = df["date1"].map(lambda x: datetime.strptime(x, "%Y.%m.%d"))
# 输入日期,并计算之间的日期差值
login = "2021.10.15"
df["login"] = datetime.strptime(login, "%Y.%m.%d").date()
df["time"] = pd.to_datetime(df["login"]) - pd.to_datetime(df["date1"])
df

在这里插入图片描述

结论:问题已经解决,没有再报错!

温馨提示:
日期计算后的数据是不能直接使用的(xxx days),需要提取时间差值并转换为数字类型

# 将计算之后的时间差值提取出来的代码:
df["time"] = df["time"].astype("str").map(lambda x: x.split())
df["time"] = df["time"].str[0].astype(int)
df

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值