微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Spark Java中将数组分解为多列

如何解决如何在Spark Java中将数组分解为多列

我有特定的数据框

+-------+----------------------+
|BlockId|Entity_BlockNumberList|
+-------+----------------------+
|      1|      [[1,4],[3,5]]|
|      2|      [[1,5]]|
|      3|      [[2,[4,4]]|
|      4|      [[2,4]]|
|      5|      [[2,5]]|
|      6|      [[3,5],[5,3]]|
|      7|      [[1,4]]|
|      8|  [[3,...|
|      9|  [[1,[2,...|
+-------+----------------------+

我想为第二列中的嵌套数组的每个元素创建多个列 像这样

BlockId | Entity_BlockNumberList | 1st Array | 2nd Array | ...

类似的东西爆炸,但是使用Javadoc在列中 我在互联网上找到了此代码

val numCols = df
  .withColumn("letters_size",size($"letters"))
  .agg(max($"letters_size"))
  .head()
  .getInt(0)

df
  .select(
    (0 until numCols).map(i => $"letters".getItem(i).as(s"col$i")): _*
  )
  .show()

这是在scala中,但我完全不知道如何使用Java来执行选择功能,尤其是(直到numCols为0)。

示例: 输入:

+---------+
|  letters|
+---------+
|[a,b,c]|
|[d,e,f]|
|     null|
+---------+

预期输出

+----+----+----+
|col0|col1|col2|
+----+----+----+
|   a|   b|   c|
|   d|   e|   f|
|null|null|null|
+----+----+----+

但不是硬编码的,因为我的数组长度不一样。

我尝试过

df.selectExpr(df.select(
                expr("concat('struct(',concat_ws(',',transform(sequence(0,max(size(entities))-1),x -> concat('entities[',x,'] as col',x))),') as columns')")
                ).as(Encoders.STRING()).head()).show();

输出如下:

+------------+
|     columns|
+------------+
|    [1,3,]|
|    [1,]|
|    [2,4,]|
|    [3,5,]|
|[3,6]|
|  [1,2,]|
+------------+

解决方法

以下代码将在scalajava中使用

df.show(false)
+---------+
|letters  |
+---------+
|[a,b,c]|
|[d,e,f]|
|[]       |
+---------+
val colExpr = df.select(
        expr("concat('struct(',concat_ws(',',transform(sequence(0,max(size(letters))-1),x -> concat('letters[',x,'] as col',x))),') as columns')")
    )
    .as[String]
    .head

colExpr的值为struct(letters[0] as col0,letters[1] as col1,letters[2] as col2) as columns

您可以直接在df.selectExpr(colExpr)中使用它,也可以像下面这样使用。


df
.withColumn("columns",expr(colExpr))
.select($"letters",$"columns.*")
.show(false)

+---------+----+----+----+
|letters  |col0|col1|col2|
+---------+----+----+----+
|[a,c]|a   |b   |c   |
|[d,f]|d   |e   |f   |
|[]       |null|null|null|
+---------+----+----+----+
,

要达到我想要的效果并且在嵌套数组中所做的最好的事情就是这样做。

for (int i; i < numCols; i++) {
    df = df.withColumn("c" + i,df.col("entities").getItem(i));
}

输出:

+-----+------------+---+---+----+----+
|block|    entities| c0| c1|  c2|  c3|
+-----+------------+---+---+----+----+
|    1|      [1,3]|  1|  3|null|null|
|    2|      [1,3]|  1|  3|null|null|
|    3|      [2,4]|  2|  4|null|null|
|    4|      [2,4]|  2|  4|null|null|
|    5|      [2,3]|  2|  3|null|null|
|    6|      [3,5]|  3|  5|null|null|
|    7|      [1,4]|  1|  4|null|null|
|    8|[3,4,5,6]|  3|  4|   5|   6|
|    9|   [1,2,5]|  1|  2|   5|null|
+-----+------------+---+---+----+----+

Kinda为接下来要做的事情工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。