我正在做一个项目,我正在处理一些具有复杂模式/数据结构的嵌套JSON日期。基本上,我想要做的是过滤掉数据帧中的一列,这样我就可以选择数组中的最后一个元素。我完全不知道该怎么做。我希望这是有意义的。
下面是我试图实现的一个示例:
val singersDF = Seq(
("beatles", "help,hey,jude"),
("romeo", "eres,mia"),
("elvis", "this,is,an,example")
).toDF("name", "hit_songs")
val actualDF = singersDF.withColumn(
"hit_songs",
split(col("hit_songs"), "\\,")
)
actualDF.show(false)
actualDF.printSchema()
+-------+-----------------------+
|name |hit_songs |
+-------+-----------------------+
|beatles|[help, hey, jude] |
|romeo |[eres, mia] |
|elvis |[this, is, an, example]|
+-------+-----------------------+
root
|-- name: string (nullable = true)
|-- hit_songs: array (nullable = true)
| |-- element: string (containsNull = true)
输出的最终目标如下:选择hit_songs数组中的最后一个“字符串”。
我并不担心模式之后会是什么样子。
+-------+---------+
|name |hit_songs|
+-------+---------+
|beatles|jude |
|romeo |mia |
|elvis |example |
+-------+---------+
发布于 2018-05-30 05:23:26
您可以使用size
函数来计算数组中所需项的索引,然后将其作为Column.apply
的参数传递(显式或隐式):
import org.apache.spark.sql.functions._
import spark.implicits._
actualDF.withColumn("hit_songs", $"hit_songs".apply(size($"hit_songs").minus(1)))
或者:
actualDF.withColumn("hit_songs", $"hit_songs"(size($"hit_songs").minus(1)))
发布于 2018-05-30 05:26:27
这里有一种方法:
val actualDF = Seq(
("beatles", Seq("help", "hey", "jude")),
("romeo", Seq("eres", "mia")),
("elvis", Seq("this", "is", "an", "example"))
).toDF("name", "hit_songs")
import org.apache.spark.sql.functions._
actualDF.withColumn("total_songs", size($"hit_songs")).
select($"name", $"hit_songs"($"total_songs" - 1).as("last_song"))
// +-------+---------+
// | name|last_song|
// +-------+---------+
// |beatles| jude|
// | romeo| mia|
// | elvis| example|
// +-------+---------+
发布于 2019-08-06 02:41:22
还可以使用UDF,如下所示:
val lastElementUDF = udf((array: Seq[String]) => array.lastOption)
actualDF.withColumn("hit_songs", lastElementUDF($"hit_songs"))
array.lastOption
将返回None
或Some
,如果数组为空,array.last
将抛出异常。
https://stackoverflow.com/questions/50592990
复制相似问题