2016-02-15 18 views
2

我想在Scala中定義將字符串列表作爲輸入的函數,並將它們轉換爲傳遞給下面代碼中使用的dataframe數組參數的列。在Spark Sql中創建字符串列表中的文字和列的數組

val df = sc.parallelize(Array((1,1),(2,2),(3,3))).toDF("foo","bar") 
val df2 = df 
     .withColumn("columnArray",array(df("foo").cast("String"),df("bar").cast("String"))) 
     .withColumn("litArray",array(lit("foo"),lit("bar"))) 

更具體而言,我想創建函數colFunction和litFunction(或如果可能的話只有一個函數),其採用的字符串的列表作爲輸入參數,並且可以使用如下:

val df = sc.parallelize(Array((1,1),(2,2),(3,3))).toDF("foo","bar") 
val colString = List("foo","bar") 
val df2 = df 
     .withColumn("columnArray",array(colFunction(colString)) 
     .withColumn("litArray",array(litFunction(colString))) 

我已經嘗試將colString映射到具有所有轉換的列的數組,但這不起作用。關於如何實現這一點的任何想法?非常感謝您閱讀此問題以及任何建議/解決方案。

回答

11

火花2.2+

支持SeqMapTuplestruct)文字已在SPARK-19254加入。據to tests

import org.apache.spark.sql.functions.typedLit 

typedLit(Seq("foo", "bar")) 

星火< 2.2

只是map與​​3210,敷用array

def asLitArray[T](xs: Seq[T]) = array(xs map lit: _*) 

df.withColumn("an_array", asLitArray(colString)).show 
// +---+---+----------+ 
// |foo|bar| an_array| 
// +---+---+----------+ 
// | 1| 1|[foo, bar]| 
// | 2| 2|[foo, bar]| 
// | 3| 3|[foo, bar]| 
// +---+---+----------+ 

關於從Seq[String]到類型Array這一功能Column改造已經提供:

def array(colName: String, colNames: String*): Column 

def array(cols: Column*): Column 

實施例:

val cols = Seq("bar", "foo") 

cols match { case x::xs => df.select(array(x, xs:_*)) 
// or 
df.select(array(cols map col: _*)) 

當然所有列必須是相同的類型。

+0

請原諒我的無知,但那叫做什麼? '數組(xs map lit:_ *)',似乎讓我感到困惑。 –

+0

@AlbertoBonsanto你是理所當然的;)認真地說,雖然它是解壓參數的斯卡拉方法。我們在這裏使用的'array'實現具有以下簽名:'array(cols:Column *)'其中'*'表示可變參數。這意味着它可以被稱爲'array(x,y,z)'。由於我們傳遞了一個序列,所以必須將其解包,並用':_ *'標記。它相當於Python'def foo(* args):...; foo(* [x,y,z])'。 – zero323

+0

非常感謝@ zero323!我仍然無法弄清楚如何在我的問題中定義我稱之爲colFunction(colString)的地方,我需要返回列值(而不是文字)的數組。這也可以使用與您提供的功能類似的功能嗎? –

相關問題