使用scala和spark将列表值与case类进行比较

g0czyy6m  于 2021-05-27  发布在  Spark
关注(0)|答案(1)|浏览(583)

我有一个如下的Dataframe。

+-------+------+-------+-------+
| num1  | num2 |   x   |   y   |
+-------+------+-------+-------+
|    25 |   10 | a&c   | i&j&k |
|    35 |   15 | a&b&d | i&k   |
+-------+------+-------+-------+

我有另一个Dataframe结构,它的头像,

num1, num2, a, b, c, d, i, j, k

我想从符号“&”中拆分x和y的列数据。然后检查分割的数据是否与上面的标题匹配,同时考虑num1和num2列。如果是这样,则用1填充值,否则用0填充值。
所需输出为:

+-------+------+---+---+---+---+---+---+---+
| num1  | num2 | a | b | c | d | i | j | k |
+-------+------+---+---+---+---+---+---+---+
|    25 |   10 | 1 | 0 | 1 | 0 | 1 | 1 | 1 |
|    35 |   15 | 1 | 1 | 0 | 1 | 1 | 0 | 1 |
+-------+------+---+---+---+---+---+---+---+

我用如下方法实现了上述输出。我创建了另一个Dataframe,与第一个Dataframe相同,但是x和y包含一个拆分数据数组,如下所示。

+------+-------+---------+---------+
| num1 | num2  |    x    |    y    |
+------+-------+---------+---------+
|   25 |    10 | [a,c]   | [i,j,k] |
|   35 |    15 | [a,b,d] | [i,k]   |
+------+-------+---------+---------+

然后就按照这个问题的解决办法
虽然它给了我精确的解,但对于有很多列如x和y的情况,它是无效的。
所以现在我想创建一个case类,并通过将标题值拆分为一个列表来匹配x,y列中的数据。有没有可能或者有其他的解决办法?有人能帮我吗?

mwecs4sa

mwecs4sa1#

在尝试了几种方法之后,我终于想出了下面的解决办法。我找到了解决方案,对这个问题的答案做了一些修改:使用scala和spark将一个数组列的行与另一个Dataframe的头进行比较。它也适用于多个数组列。这是它的代码。

val df = Seq((25, 10, "a&c", "i&j&k"), (35, 15, "a&b&d", "i&k")
      .toDF("num1", "num2", "x", "y")
  val dfProcessed = df.withColumn("x", split($"x", "&"))
      .withColumn("y", split($"y", "&"))
      .select("num1", "num2", "x", "y")

    val headers = Seq("a", "b", "c", "d", "i", "j", "k")
    val report = dfProcessed.select(Seq("num1", "num2").map(col) ++ headers.map(line => array_contains('x, line)
      || array_contains('y, line) as line) : _*)

    report.show()

我想这可能对你有帮助。

相关问题