[英]Setting the column value based on the column value of complete df in spark scala
[英]Convert String and Compare with DF Column Value Spark Scala
我有一个val current_dates = "A:2021-04-02,B:2021-04-02,C:2021-04-01,D:2021-04-01"
类型的字符串。 这里A,B,C,D
是 id 字段及其对应的日期。
现在我有一个输入 dataFrame 有多个记录有 id 的 & 日期列。
val input_df = sc.parallelize(Seq(("A","2021-04-01"),("A","2021-04-02"),("B","2021-04-01"),("B","2021-04-02"),("C","2021-04-01"),("C","2021-04-02"),("D","2021-04-01"),("D","2021-04-02"))).toDF("id","create_date")
input_df.show()
+---+-----------+
| id|create_date|
+---+-----------+
| A| 2021-04-01|
| A| 2021-04-02|
| B| 2021-04-01|
| B| 2021-04-02|
| C| 2021-04-01|
| C| 2021-04-02|
| D| 2021-04-01|
| D| 2021-04-02|
+---+-----------+
现在我想将每个记录的日期值与字符串中每个 id 的相应日期进行比较,并在 dataFrame 中派生新的日期列。
expected_df.select((input_df.columns ++ Array("new_dt")).head, (input_df.columns ++ Array("new_dt")).tail: _*).orderBy("id").show()
+---+-----------+----------+
| id|create_date| new_dt|
+---+-----------+----------+
| A| 2021-04-01|2021-04-02|
| A| 2021-04-02|2021-04-02|
| B| 2021-04-02|2021-04-02|
| B| 2021-04-01|2021-04-02|
| C| 2021-04-02|2021-04-02|
| C| 2021-04-01|2021-04-01|
| D| 2021-04-01|2021-04-01|
| D| 2021-04-02|2021-04-02|
+---+-----------+----------+
目前,我正在将字符串转换为另一个 dataframe 并将其与输入 dataframe 连接并以下列方式派生新列。
val current_dates_df = sc.parallelize(current_dates.split(",").map(_.split(":")).map{ case Array(a,b) => (a, b) }).toDF("previous_run_id", "previous_run_date")
current_dates_df.show()
+---------------+-----------------+
|previous_run_id|previous_run_date|
+---------------+-----------------+
| A| 2021-04-02|
| B| 2021-04-02|
| C| 2021-04-01|
| D| 2021-04-01|
+---------------+-----------------+
val deriveNewDt: UserDefinedFunction = udf[String, String, String]((create_date: String, previous_run_date: String) => {
val date_format: String = "yyyy-MM-dd"
val new_dt = {
if (new SimpleDateFormat(date_format).parse(create_date).after(new SimpleDateFormat(date_format).parse(previous_run_date))) create_date
else previous_run_date
}
new_dt
})
val joined_df = input_df.join(current_dates_df, input_df("id") === current_dates_df("previous_run_id"), "left_outer")
val expected_df = joined_df.withColumn("new_dt", deriveNewDt($"create_date", $"previous_run_date"))
expected_df.select((input_df.columns ++ Array("new_dt")).head, (input_df.columns ++ Array("new_dt")).tail: _*).show()
是否有更好的方法来处理字符串并实现相同的功能,而无需将字符串转换为 DataFrame。
您可以使用str_to_map
获取给定id
的日期,并使用greatest
获取两者之间的较晚日期:
val current_dates = "A:2021-04-02,B:2021-04-02,C:2021-04-01,D:2021-04-01"
val result = input_df.withColumn(
"new_dt",
expr(s"greatest(str_to_map('$current_dates, ',', ':')[id], create_date)")
)
result.show
+---+-----------+----------+
| id|create_date| new_dt|
+---+-----------+----------+
| A| 2021-04-01|2021-04-02|
| A| 2021-04-02|2021-04-02|
| B| 2021-04-01|2021-04-02|
| B| 2021-04-02|2021-04-02|
| C| 2021-04-01|2021-04-01|
| C| 2021-04-02|2021-04-02|
| D| 2021-04-01|2021-04-01|
| D| 2021-04-02|2021-04-02|
+---+-----------+----------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.