You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark pandas中两日期列天数差的高效计算方法

计算PySpark pandas DataFrame中日期列的天数差

问题背景

在原生pandas中,将两列datetime64类型的日期相减后,可通过.dt.days直接获取天数差;但在PySpark pandas(以下简称ps)中,两日期列直接相减会返回以秒数为单位的整数(如示例中的[-259200, 0, -86400, -86400, -86400, -86400]),无法直接得到天数格式。尝试将该整数列转为datetime类型会得到1970年左右的无效日期,而将数据转回原生pandas处理虽能得到正确结果,但大数据量下会带来额外开销、延长运行时间,因此需要高效的分布式实现方式。

示例代码:

import pandas as pd
import pyspark.pandas as ps

data = {
    "d1": [
        "2019-05-18",
        "2019-06-21",
        "2019-05-08",
        "2019-05-22",
        "2019-11-20",
        "2019-05-29",
    ],
    "d2": [
        "2019-05-21",
        "2019-06-21",
        "2019-05-09",
        "2019-05-23",
        "2019-11-21",
        "2019-05-30",
    ],
}
df = pd.DataFrame(data)
df[["d1", "d2"]] = df[["d1", "d2"]].astype("datetime64")
pdf = ps.from_pandas(df)

# 原生pandas的正确结果
df["diff"] = (df["d1"] - df["d2"]).dt.days
# PySpark pandas直接相减得到秒数
pdf["diff_seconds"] = pdf["d1"] - pdf["d2"]

原生pandas输出的天数差:[-3, 0, -1, -1, -1, -1]

高效解决方案

方法1:秒数直接转换为天数

既然相减结果是秒数,直接除以一天的秒数(86400)并做整数除法即可,简洁且无额外依赖:

pdf["diff_days"] = (pdf["d1"] - pdf["d2"]) // 86400

该方法保证结果为整数天数,与原生pandas输出完全一致。

方法2:使用PySpark内置函数datediff

通过PySpark pandas的ps.sql接口调用Spark原生的datediff函数,分布式执行更适合大数据量场景:

pdf["diff_days"] = ps.sql("SELECT datediff(d1, d2) FROM {pdf}")

注意:datediff参数顺序为datediff(endDate, startDate),结果为endDate - startDate的天数,与示例中d1 - d2逻辑匹配。

方法3:利用PySpark pandas的dt属性

将日期相减结果转为Timedelta类型,再通过.dt.days获取天数,贴近原生pandas使用习惯:

pdf["diff_days"] = ps.Series(pdf["d1"] - pdf["d2"], dtype="timedelta64[ns]").dt.days

验证结果

以上三种方法最终得到的diff_days列结果均为:[-3, 0, -1, -1, -1, -1],与原生pandas输出一致,且无需将数据拉回本地处理。

内容的提问来源于stack exchange,提问作者Rudra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 15:50:19