【问题标题】:Data transformation in Spark ScalaSpark Scala 中的数据转换
【发布时间】:2017-02-27 09:17:51
【问题描述】:

我有以下数据框

+-----+-----+-----+ .......+-------+
|item1|item2|item3|........| itemN |
+-----+-----+-----+........|-------+
|   v1|   v2|   v3|........| vN----+
|   v4|   v5|   v6|........| v2N---+
+-----+-----+-----+........|-------+ 

这里 item1 、 item2 和 item3 是列名,表由 1 行 v1,v2,v3 组成。

我想把它变成

colA   colB
item1    v1
item2    v2
item3    v3
 .        .
 .        .
 .        . 

这里有两列,可以说 colA 和 colB,行如图所示。

如何使用 scala 在 spark 中进行这种转换?

【问题讨论】:

标签: sql scala apache-spark


【解决方案1】:

你可以使用explode:

import org.apache.spark.sql.functions._

input.show()
// +-----+-----+-----+
// |item1|item2|item3|
// +-----+-----+-----+
// |   v1|   v2|   v3|
// |   v4|   v5|   v6|
// +-----+-----+-----+

val columns: Array[String] = input.columns

val result = input.explode(columns.map(s => col(s)): _*) {
  r: Row => columns.zipWithIndex.map { case (name, index) => (name, r.getAs[String](index)) }
}.select($"_1" as "colA", $"_2" as "colB")

result.show()
// +-----+----+
// | colA|colB|
// +-----+----+
// |item1|  v1|
// |item2|  v2|
// |item3|  v3|
// |item1|  v4|
// |item2|  v5|
// |item3|  v6|
// +-----+----+

【讨论】:

  • 感谢上面的代码。我还有一个问题,如果初始表中的列数(即item1,item2 ......item n)非常大,那么上面的事情怎么办?
  • 多大?为什么上述代码不适用于任何(有效)数量的列?
  • 我不知道最初的列数可以说有 100 列。我认为上面的代码将变量 i1,i2,i3 对应于列,所以如果有很多列,这将如何工作?
  • 谢谢,如果值 v1,v2 .... 是复杂类型(比如数组)而不是字符串,那么我必须在上面的代码中进行哪些更改
  • 至少它们都是同一类型吗?如果是,只需将 r.getAs[String] 更改为 r.getAs[T] ,其中 T 是您期望的类型,例如它可以是 Array[String]Array[(Int, String)] 或其他...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 2018-12-05
  • 1970-01-01
  • 2017-06-11
相关资源
最近更新 更多