有没有办法将pyspark.sql.functions.date_add和col(';column_name';)用作第二个参数而不是静态整数?

有没有办法将pyspark.sql.functions.date_add和col(';column_name';)用作第二个参数而不是静态整数?,pyspark,Pyspark,在ETL过程中,我有一个5位整数格式的SAS日期字段,表示自1960年1月1日起的天数。为了使此数据列在分析中更有用,我想将该列转换为红移中的日期数据类型字段 目前,我正尝试在pyspark中执行以下操作: 创建了带有字符串文字“1960-01-01”的新列“sas_date” 使用pyspark.sql.function.date_add将“sas日期”列作为 开始日期参数和整数值“到达日期”列作为第二个参数 当date_add函数运行时,我得到了error列not iterable,即使我

在ETL过程中,我有一个5位整数格式的SAS日期字段,表示自1960年1月1日起的天数。为了使此数据列在分析中更有用,我想将该列转换为红移中的日期数据类型字段

目前,我正尝试在pyspark中执行以下操作:

  • 创建了带有字符串文字“1960-01-01”的新列“sas_date”

  • 使用pyspark.sql.function.date_add将“sas日期”列作为 开始日期参数和整数值“到达日期”列作为第二个参数

  • 当date_add函数运行时,我得到了error列not iterable,即使我认为arrival_date列是一个系列,这意味着它是iterable。但它不是,为什么

  • 当我删除'arrival_date'列并将其替换为静态整数值(例如1)时,date_add函数将起作用

i94=i94.withColumn('arrival\u date',col('arrival\u date').cast(Int())
i94=i94。带列('sas_date',点亮(“1960-01-01”))
i94=i94。带列('arrival_date',date_add(列('sas_date'),i94['arrival_date']))
我希望能够传递我的列,以便第二个日期添加参数将是动态的。然而,date_add似乎不接受这一点?如果date_addd不能实现这一点,除了使用自定义项,我还有什么其他选择

更新: 日期添加()操作之前的数据状态

i94.printSchema()

|--cic_id:double(nullable=true)

|--visa_id:字符串(可空=真)

|--端口id:字符串(nullable=true)

|--航空公司id:string(nullable=true)

|--cit_id:double(nullable=true)

|--res_id:double(nullable=true)

|--年份:双精度(可空=真)

|--月份:双倍(可空=真)

|--年龄:双倍(可空=真)

|--性别:字符串(nullable=true)

|--到达日期:整数(nullable=true)

|--出发日期:双倍(可空=真)

|--开始日期:字符串(nullable=true)

|--日期\结束:字符串(nullable=true)

|--sas_日期:字符串(nullable=false)

i94.限制(10).toPandas()

我认为你是绝对正确的,
date\u add
被设计为只接受
int
值,直到Spark我认为你是绝对正确的,
date\u add
被设计为只接受
int
值,直到Spark它应该适合你的方法。你能展示一些样本数据吗,对吗@SMaZ?虽然我想我刚刚意识到它为什么会这样。当使用withColumn('arrival_date',…)时,我认为spark在应用date_add sql函数之前会覆盖'arrival_date'列。稍后我将测试这个理论,如果我是对的,我将更新这个问题的答案。a@Mabloq:您无需评估
到达日期
两次。你能在第一个位置显示诸如到达日期值之类的数据吗?请注意,SAS将所有数字存储为浮点。所以,也许您只需要将原始天数变量值转换为整数,就可以使用date_add()?嘿@SMaZ谢谢您一直支持我。我用模式数据和10行样本编辑了我的问题。我的理论被证明是错误的:(它应该适用于你的方法。你能展示一些样本数据,对吗@SMaZ?尽管我想我刚刚意识到为什么它会这样做。当使用withColumn('arrival_date')时,…)我认为spark甚至在应用date\u add sql函数之前就已经覆盖了“arrival\u date”列。我稍后将测试这一理论,如果我是对的,将更新问题的答案。a@Mabloq:您不需要计算两次
到达日期
。是否可以首先显示到达日期值之类的数据。请注意,SAS存储所有数字都是浮点数。因此,也许您只需要将原始天数变量值转换为整数,就可以使用date_add()?Hey@SMaZ感谢您坚持我的观点。我用模式数据和10行样本编辑了我的问题。我的理论被证明是错误的:(谢谢,很好地从源代码中挖掘出来。也很高兴知道列选项将在3.0中可用。同时,作为未来的comer的参考,udf方法已经过测试并成功运行。再次感谢@SMazThank you,很好地从源代码中挖掘出来。也很高兴知道列选项将在3.0中可用。也用于未来的comer的r。)作为参考,udf方法已经过测试并取得了成功。再次感谢@SMaz
import pyspark.sql.functions as f
import pyspark.sql.types as t
from datetime import datetime
from datetime import timedelta

l1 = [(5748517.0,'1960-01-01', 20574), (5748517.0,'1960-01-01', 20574), (5748517.0,'1960-01-01', 20574)]
df = spark.createDataFrame(l1).toDF('cic_id','sas_date','arrival_date')
df.show()
+---------+----------+------------+
|   cic_id|  sas_date|arrival_date|
+---------+----------+------------+
|5748517.0|1960-01-01|       20574|
|5748517.0|1960-01-01|       20574|
|5748517.0|1960-01-01|       20574|
+---------+----------+------------+
def date_add_(date, days):

    # Type check and convert to datetime object
    # Format and other things should be handle more delicately
    if type(date) is not datetime:
        date = datetime.strptime('1960-01-01', "%Y-%m-%d")
    return date + timedelta(days)


date_add_udf = f.udf(date_add_, t.DateType())

df.withColumn('actual_arrival_date', date_add_udf(f.to_date('sas_date'), 'arrival_date')).show()
+---------+----------+------------+-------------------+
|   cic_id|  sas_date|arrival_date|actual_arrival_date|
+---------+----------+------------+-------------------+
|5748517.0|1960-01-01|       20574|         2016-04-30|
|5748517.0|1960-01-01|       20574|         2016-04-30|
|5748517.0|1960-01-01|       20574|         2016-04-30|
+---------+----------+------------+-------------------+

df.withColumn('new_arrival_date', f.expr("date_add(sas_date, arrival_date)")).show()
+---------+----------+------------+----------------+
|   cic_id|  sas_date|arrival_date|new_arrival_date|
+---------+----------+------------+----------------+
|5748517.0|1960-01-01|       20574|      2016-04-30|
|5748517.0|1960-01-01|       20574|      2016-04-30|
|5748517.0|1960-01-01|       20574|      2016-04-30|
+---------+----------+------------+----------------+