Объедините несколько столбцов ArrayType в Spark в один столбец ArrayType - PullRequest
0 голосов
/ 30 августа 2018

Я хочу объединить несколько столбцов ArrayType [StringType] в spark, чтобы создать один ArrayType [StringType]. Для объединения двух столбцов я нашел солютон здесь:

Объединение двух столбцов SQL типа Spark типа Array [string] в новый столбец Array [string]

Но как мне объединиться, если я не знаю количество столбцов во время компиляции? Во время выполнения я буду знать имена всех столбцов, которые нужно объединить.

Один из вариантов - использовать UDF, определенный в приведенном выше вопросе stackoverflow, чтобы добавить два столбца несколько раз в цикле. Но это включает в себя несколько чтений на весь фрейм данных. Есть ли способ сделать это за один раз?

+------+------+---------+
| col1 | col2 | combined|
+------+------+---------+
| [a,b]| [i,j]|[a,b,i,j]|
| [c,d]| [k,l]|[c,d,k,l]|
| [e,f]| [m,n]|[e,f,m,n]|
| [g,h]| [o,p]|[g,h,o,p]|
+------+----+-----------+

1 Ответ

0 голосов
/ 30 августа 2018
val arrStr: Array[String] = Array("col1", "col2")

val arrCol: Array[Column] = arrString.map(c => df(c))

val assembleFunc = udf { r: Row => assemble(r.toSeq: _*)}

val outputDf = df.select(col("*"), assembleFunc(struct(arrCol: 
_*)).as("combined"))

def assemble(rowEntity: Any*): 
                    collection.mutable.WrappedArray[String] = {

 var outputArray = 
 rowEntity(0).asInstanceOf[collection.mutable.WrappedArray[String]]

  rowEntity.drop(1).foreach {
    case v: collection.mutable.WrappedArray[String] =>
      outputArray ++= v
    case null =>
      throw new SparkException("Values to assemble cannot be 
      null.")
    case o =>
      throw new SparkException(s"$o of type ${o.getClass.getName} 
      is not supported.")
 }

outputArray
}

outputDf.show(false)    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...