2017-09-14 37 views
0

我有兩列與字符串數組火花SQL - 陣列的陣列到單一陣列

| ColA | ColB | 
|------|------| 
| ["a"]| ["b"]| 

我想從兩個陣列」

| ColAplusB | 
|-----------| 
|["a", "b"] | 

的創建包含值的單個柱我試過array(ColA, ColB)這給我留下了:

| ColAplusBnested | 
|-----------------| 
| [["a"], ["b"]] | 

我怎麼能得到想要的結果(陣列數組中的y與來自初始數組的值相交換)?

+0

搜索長期'扁平數組/集合'。我不知道火花,但我相信它應該是可行的,沒有自定義代碼。 – lad2025

+0

我相信扁平化會將其降低到每行單個值,這並不完全是我正在尋找的。 'explode'就是這樣做的,但是我不確定如何將所有值選回單個數組。 – 3yakuya

+0

我的意思是像'flatten(array(ColA,ColB))' – lad2025

回答

1

我們假設你的數據是這樣的:

val df = spark.sqlContext.createDataFrame(Seq(
    (Array("a"), Array("b")) 
)).toDF("ColA", "ColB") 
df.printSchema() 
df.show() 

root 
|-- ColA: array (nullable = true) 
| |-- element: string (containsNull = true) 
|-- ColB: array (nullable = true) 
| |-- element: string (containsNull = true) 

+----+----+ 
|ColA|ColB| 
+----+----+ 
| [a]| [b]| 
+----+----+ 

existing set of Spark SQL functions沒有出現有陣列(或序列)級聯功能。我只看到concat函數的字符串。但是你可以創建一個簡單的用戶定義函數(UDF):

import org.apache.spark.sql.functions.udf 

val concatSeq = udf { (x: Seq[String], y: Seq[String]) => x ++ y } 
val df2 = df.select(concatSeq('ColA, 'ColB).as("ColAplusB")) 
df2.printSchema() 
df2.show() 

root 
|-- ColAplusB: array (nullable = true) 
| |-- element: string (containsNull = true) 

+---------+ 
|ColAplusB| 
+---------+ 
| [a, b]| 
+---------+ 

要執行(例如排序,刪除重複),可以在你的UDF做任何額外的邏輯:

val df = spark.sqlContext.createDataFrame(Seq(
    (Array("b", "a", "c"), Array("a", "b")) 
)).toDF("ColA", "ColB") 

df.show() 

+---------+------+ 
|  ColA| ColB| 
+---------+------+ 
|[b, a, c]|[a, b]| 
+---------+------+ 

val concatSeq = udf { (x: Seq[String], y: Seq[String]) => 
    (x ++ y).distinct.sorted 
} 

df.select(concatSeq('ColA, 'ColB).as("ColAplusB")).show() 

+---------+ 
|ColAplusB| 
+---------+ 
|[a, b, c]| 
+---------+