首页 > 解决方案 > 计算 spark.sql 数据库列中包含的列表中特定元素的最长序列

问题描述

我有以下我想解决的问题。

我有以下从查询创建的数据框

val temp = spark.sql("select Id, collect_list(from) as letter from f group by Id")

|Id|                letter|
+-----------+---------------+
|      106|            [c]|
|      101|            [p]|
|      104|[c, c, c, t, u]|
|      100|[d, t, j, j, c]|
|      110|      [p, n, f]|
|      113|[s, c, c, b, ..|
|      115|[u, s, t, c, ..|
|       11|   [c, c, i, s]|
|      117|   [d, d, p, s]|
|      118|[a, s, c, t, ..|
|      123|         [d, n]|
|      125|         [n, b]|
|      128|            [c]|
|      131|   [c, t, c, u]|
|      132|      [c, u, i]|
|      134|[c, p, j, u, c]|
|      136|[b, a, t, n, c]|
|      137|         [b, a]|
|      138|      [b, t, c]|
|      141|            [s]| 

我想创建一个名为“n”的新列 此列将包含一个数值,它表示在“c”出现之前单元格中最长的字母序列。最长的序列可以在列表中的任何位置。

例如,本节的解决方案列(假设没有任何内容被 .... 截断)将是

0, 1, 3, 5, 3, 2, 4, 4, 4, 4, 2, 2, 1, 4, 2, 5, 5, 2, 3, 1

任何帮助将不胜感激。谢谢!

标签: sqlscalaapache-sparkapache-spark-sql

解决方案


这是使用 spark 的方法functions,您可以使用 spark 转换给定的 scala 函数,functions如下所示

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     |
+-----------+--------------------+------+

推荐阅读