向数据帧添加新列时出现问题-spark/scala
我是spark/scala的新手。我正在尝试将配置单元表中的一些数据读取到spark数据帧,然后根据某些条件添加一列。这是我的密码:向数据帧添加新列时出现问题-spark/scala,scala,apache-spark,dataframe,apache-spark-sql,user-defined-functions,Scala,Apache Spark,Dataframe,Apache Spark Sql,User Defined Functions,我是spark/scala的新手。我正在尝试将配置单元表中的一些数据读取到spark数据帧,然后根据某些条件添加一列。这是我的密码: val DF = hiveContext.sql("select * from (select * from test_table where partition_date='2017-11-22') a JOIN (select max(id) as bid from test_table where partition_date='2017-11-22' gr
val DF = hiveContext.sql("select * from (select * from test_table where partition_date='2017-11-22') a JOIN (select max(id) as bid from test_table where partition_date='2017-11-22' group by at_id) b ON a.id=b.bid")
def dateDiff(partition_date: org.apache.spark.sql.Column, item_due_date: org.apache.spark.sql.Column): Long ={
ChronoUnit.DAYS.between(LocalDate.parse(partition_date.toString()), LocalDate.parse(item_due_date.toString))
}
val finalDF = DF.withColumn("status",
when(col("past_due").equalTo(1) && !(col("item_due_date").equalTo(null) || col("item_due_date").equalTo("NULL") || col("item_due_date").equalTo("null")) && (dateDiff(col("partition_date"),col("item_due_date")) < 0) && !(col("item_decision").equalTo(null) || col("item_decision").equalTo("NULL") || col("item_decision").equalTo("null")), "approved")
.when(col("past_due").equalTo(1) && !(col("item_due_date").equalTo(null) || col("item_due_date").equalTo("NULL") || col("item_due_date").equalTo("null")) && (dateDiff(col("partition_date"),col("item_due_date")) < 0) && (col("item_decision").equalTo(null) || col("item_decision").equalTo("NULL") || col("item_decision").equalTo("null")), "pending")
.when(col("past_due").equalTo(1) && !(col("item_due_date").equalTo(null) || col("item_due_date").equalTo("NULL") || col("item_due_date").equalTo("null")) && (dateDiff(col("partition_date"),col("item_due_date")) >= 0), "expired")
.otherwise("null"))
我使用的列的数据示例来自DF
:
|-- item_due_date: string (nullable = true)
|-- past_due: integer (nullable = true)
|-- item_decision: string (nullable = true)
|-- partition_date: string (nullable = true)
+--------+-------------+-------------+--------------+
|past_due|item_due_date|item_decision|partition_date|
+--------+-------------+-------------+--------------+
| 1| 0001-01-14| null| 2017-11-22|
| 1| 0001-01-14| Mitigate| 2017-11-22|
| 1| 0001-01-14| Mitigate| 2017-11-22|
| 1| 0001-01-14| Mitigate| 2017-11-22|
| 0| 2018-03-18| null| 2017-11-22|
| 1| 2016-11-30| null| 2017-11-22|
+--------+-------------+-------------+--------------+
我还尝试使用自定义自定义自定义项:
def status(past_due: Int, item_decision: String, maxPartitionDate: String, item_due_date: String): String = {
if (past_due == 1 && item_due_date != "NULL") {
if (ChronoUnit.DAYS.between(LocalDate.parse(maxPartitionDate.trim), LocalDate.parse(item_due_date.trim)) < 0) {
if (item_decision != "NULL") "pending"
else "approved"
} else "expired"
} else "NULL"
}
val statusUDF = sqlContext.udf.register("statusUDF", status _)
val DF2 = DF.withColumn("status", statusUDF(DF("past_due"),DF("item_decision"),DF("partition_date"),DF("item_due_date")))
DF2.show()
任何帮助都将不胜感激。谢谢大家! 您只需使用
datediff
内置函数检查两列之间的天数差异。您不需要编写函数或udf
函数。当函数也被修改时
import org.apache.spark.sql.functions._
val finalDF = DF.withColumn("status",
when(col("past_due").equalTo(1) && col("item_due_date").isNotNull && !(lower(col("item_due_date")).equalTo("null")) && (datediff(col("partition_date"),col("item_due_date")) < 0) && col("item_decision").isNotNull && !(lower(col("item_decision")).equalTo("null")), "approved")
.otherwise(when(col("past_due").equalTo(1) && col("item_due_date").isNotNull && !(lower(col("item_due_date")).equalTo("null")) && (datediff(col("partition_date"),col("item_due_date")) < 0) && (col("item_decision").isNull || lower(col("item_decision")).equalTo("null")), "pending")
.otherwise(when(col("past_due").equalTo(1) && col("item_due_date").isNotNull && !(lower(col("item_due_date")).equalTo("null")) && (datediff(col("partition_date"),col("item_due_date")) >= 0), "expired")
.otherwise("null"))))
添加状态
列作为
+--------+-------------+-------------+--------------+--------+
|past_due|item_due_date|item_decision|partition_date|status |
+--------+-------------+-------------+--------------+--------+
|1 |2017-12-14 |null |2017-11-22 |pending |
|1 |2017-12-14 |Mitigate |2017-11-22 |approved|
|1 |0001-01-14 |Mitigate |2017-11-22 |expired |
|1 |0001-01-14 |Mitigate |2017-11-22 |expired |
|0 |2018-03-18 |null |2017-11-22 |null |
|1 |2016-11-30 |null |2017-11-22 |expired |
+--------+-------------+-------------+--------------+--------+
我希望答案是有帮助的您可以简单地使用
datediff
内置函数来检查两列之间的天数差异。您不需要编写函数或udf
函数。当函数也被修改时
import org.apache.spark.sql.functions._
val finalDF = DF.withColumn("status",
when(col("past_due").equalTo(1) && col("item_due_date").isNotNull && !(lower(col("item_due_date")).equalTo("null")) && (datediff(col("partition_date"),col("item_due_date")) < 0) && col("item_decision").isNotNull && !(lower(col("item_decision")).equalTo("null")), "approved")
.otherwise(when(col("past_due").equalTo(1) && col("item_due_date").isNotNull && !(lower(col("item_due_date")).equalTo("null")) && (datediff(col("partition_date"),col("item_due_date")) < 0) && (col("item_decision").isNull || lower(col("item_decision")).equalTo("null")), "pending")
.otherwise(when(col("past_due").equalTo(1) && col("item_due_date").isNotNull && !(lower(col("item_due_date")).equalTo("null")) && (datediff(col("partition_date"),col("item_due_date")) >= 0), "expired")
.otherwise("null"))))
添加状态
列作为
+--------+-------------+-------------+--------------+--------+
|past_due|item_due_date|item_decision|partition_date|status |
+--------+-------------+-------------+--------------+--------+
|1 |2017-12-14 |null |2017-11-22 |pending |
|1 |2017-12-14 |Mitigate |2017-11-22 |approved|
|1 |0001-01-14 |Mitigate |2017-11-22 |expired |
|1 |0001-01-14 |Mitigate |2017-11-22 |expired |
|0 |2018-03-18 |null |2017-11-22 |null |
|1 |2016-11-30 |null |2017-11-22 |expired |
+--------+-------------+-------------+--------------+--------+
我希望答案有帮助您的函数是基于列的。因此,如果任何函数满足您的需求,您都可以使用它。否则,如果要在基本数据类型中进行操作,则必须使用udf函数。我尝试在和时使用udf而不是
,否则
,但在显示/保存数据帧时遇到错误。所以我转向了这种方法。有什么方法可以解决这种方法中的错误吗?您必须使用示例数据帧和数据帧的模式更新您的问题。这将帮助你得到答案quickly@Hemanth您编写的函数不是udf
,您应该仔细阅读如何编写适当的udf
。我知道它不是udf
。这是一个普通的scala函数,用于获取日期差异@提示如何使其工作的想法?您的函数是基于列的。因此,如果任何函数满足您的需求,您都可以使用它。否则,如果要在基本数据类型中进行操作,则必须使用udf函数。我尝试在和时使用udf而不是,否则
,但在显示/保存数据帧时遇到错误。所以我转向了这种方法。有什么方法可以解决这种方法中的错误吗?您必须使用示例数据帧和数据帧的模式更新您的问题。这将帮助你得到答案quickly@Hemanth您编写的函数不是udf
,您应该仔细阅读如何编写适当的udf
。我知道它不是udf
。这是一个普通的scala函数,用于获取日期差异@你有什么办法让它发挥作用吗?你是救世主!非常感谢!:)程序运行时没有任何问题,但我在状态
列中只看到过期
和空
值。逻辑上有问题吗?你的约会应该是这样的。请核对日期。:)似乎是这样。还有,我的“何时”状态也应该很好,对吧?我想知道是否有任何不同。不,当你的逻辑也有一些缺陷。我的意思是你写它的方式,因为一切都在状态栏中生成null。你可以自己试试看。调试和改进。我想你能做到你是救世主!非常感谢!:)程序运行时没有任何问题,但我在状态
列中只看到过期
和空
值。逻辑上有问题吗?你的约会应该是这样的。请核对日期。:)似乎是这样。还有,我的“何时”状态也应该很好,对吧?我想知道是否有任何不同。不,当你的逻辑也有一些缺陷。我的意思是你写它的方式,因为一切都在状态栏中生成null。你可以自己试试看。调试和改进。我想你能做到