计算spark.sql数据库列中包含的列表中特定元素的最长序列
我想解决以下问题 我从一个查询中创建了以下数据帧计算spark.sql数据库列中包含的列表中特定元素的最长序列,sql,scala,apache-spark,apache-spark-sql,Sql,Scala,Apache Spark,Apache Spark Sql,我想解决以下问题 我从一个查询中创建了以下数据帧 val temp=spark.sql(“按Id选择Id,按字母从f组收集列表”) 我想创建一个名为“n”的新列 此列将包含一个数值,该数值表示“c”出现之前单元格中最长的字母序列。最长的序列可以是列表中的任意位置 例如,本节的“解决方案”列(假设没有任何内容被…截断)将为 0,1,3,5,3,2,4,4,4,2,2,1,4,2,5,5,2,3,1 任何帮助都将不胜感激。谢谢大家! 您可以编写一个用户定义函数(udf)来计算所需的内容。有很多方法可
val temp=spark.sql(“按Id选择Id,按字母从f组收集列表”)
我想创建一个名为“n”的新列
此列将包含一个数值,该数值表示“c”出现之前单元格中最长的字母序列。最长的序列可以是列表中的任意位置
例如,本节的“解决方案”列(假设没有任何内容被…截断)将为
0,1,3,5,3,2,4,4,4,2,2,1,4,2,5,5,2,3,1
任何帮助都将不胜感激。谢谢大家! 您可以编写一个用户定义函数(udf)来计算所需的内容。有很多方法可以计算最长的序列。一种简单的方法是在“co”上拆分序列,计算每个子序列的大小并取最大值
val longuest_seq=udf((x:seq[String])=>{
x、 减少(+“”++)
.split(“*co*”)
.map(0.count(0='')+1)
麦克斯先生
})
val df=Seq(
(1,数组(“x”、“y”、“co”、“z”),
(2,数组(“x”),
(3,数组(“co”,“t”)),
(4,数组(“a”、“b”、“c”、“d”、“co”、“e”))
).toDF(“id”、“行程”)
df.带列(“n_行程”,最长顺序(“行程”)。显示
产生
+---+-------------------+-------+
|id | trip | n|u trips|
+---+-------------------+-------+
|1 |[x,y,co,z]| 2|
|2 |[x]| 1|
|3 |[co,t]| 1|
|4 |[a、b、c、d、co、e]|4|
+---+-------------------+-------+
以下是如何使用spark函数的方法,您可以使用spark函数转换给定的scala函数,如下所示
import org.apache.spark.sql.functions._
df.withColumn("n_trip",
array_max(
transform(
filter(
split(array_join($"trip", " "), "co"),
(col: Column) => (col =!= "" || col =!= null)
), (col: Column) => size(split(trim(col), " "))
)
))
.withColumn("n_trip", when($"n_trip".isNull, 0).otherwise($"n_trip"))
.show(false)
更新:易于理解
df.withColumn("split", split(array_join($"trip", " "), "co"))
.withColumn("filter", filter($"split", (col: Column) => col =!= "" || col =!= null))
.withColumn("n_trip", array_max(transform($"filter", (col: Column) => size(split(trim(col), " ")))))
.withColumn("n_trip", when($"n_trip".isNull, 0).otherwise($"n_trip"))
.drop("split", "filter")
.show(false)
输出:
+-----------+--------------------+------+
|passengerId|trip |n_trip|
+-----------+--------------------+------+
|10096 |[co] |0 |
|10351 |[pk] |1 |
|10436 |[co, co, cn, tj, us]|3 |
|1090 |[dk, tj, jo, jo, ch]|5 |
|11078 |[pk, no, fr] |3 |
|11332 |[sg, cn, co, bm] |2 |
|11563 |[us, sg, th, cn] |4 |
|1159 |[ca, cl, il, sg] |4 |
|11722 |[dk, dk, pk, sg] |4 |
|11888 |[au, se, ca, tj] |4 |
|12394 |[dk, nl] |2 |
|12529 |[no, be] |2 |
|12847 |[cn] |1 |
|13192 |[cn, tk, cg, uk] |4 |
|13282 |[co, us, iq] |2 |
|13442 |[cn, pk, jo, us, ch]|5 |
|13610 |[be, ar, tj, no, ch]|5 |
|13772 |[be, at] |2 |
|13865 |[be, th, cn] |3 |
|14157 |[sg] |1 |
+-----------+--------------------+------+
你能添加文本而不是图像吗?@koiralo done,这有帮助吗?谢谢你的回复,奥利,这实际上并没有计算我想要的内容,我如何在数据帧上使用自定义项?对不起,我复制了粘贴错误的代码。是的,我明白了,谢谢你的建议!我真的很喜欢这个解决方案,你能给我解释一下它是如何工作的吗?谢谢:)@Xaleate这主要是scala函数转换的解决方案。如果你不懂这些函数,请告诉我。你可以用withColumn一步一步地做,因为我把它做得很简短。同时检查更新的部分,这可能会帮助你一步一步地理解。谢谢Koiralo!这是有道理的。实际上我更喜欢这样,因为我很清楚。但有一件事,当我运行时,我遇到了n_trip未解决的问题,在处理之前复制的地方是否缺少一行?就是这样,谢谢:)
+-----------+--------------------+------+
|passengerId|trip |n_trip|
+-----------+--------------------+------+
|10096 |[co] |0 |
|10351 |[pk] |1 |
|10436 |[co, co, cn, tj, us]|3 |
|1090 |[dk, tj, jo, jo, ch]|5 |
|11078 |[pk, no, fr] |3 |
|11332 |[sg, cn, co, bm] |2 |
|11563 |[us, sg, th, cn] |4 |
|1159 |[ca, cl, il, sg] |4 |
|11722 |[dk, dk, pk, sg] |4 |
|11888 |[au, se, ca, tj] |4 |
|12394 |[dk, nl] |2 |
|12529 |[no, be] |2 |
|12847 |[cn] |1 |
|13192 |[cn, tk, cg, uk] |4 |
|13282 |[co, us, iq] |2 |
|13442 |[cn, pk, jo, us, ch]|5 |
|13610 |[be, ar, tj, no, ch]|5 |
|13772 |[be, at] |2 |
|13865 |[be, th, cn] |3 |
|14157 |[sg] |1 |
+-----------+--------------------+------+