2016-01-20 71 views
13

我試圖把我的輸入數據:星火:添加列到數據幀有條件

A B  C 
-------------- 
4 blah 2 
2   3 
56 foo  3 

和列基於B是否爲空或不添加到末尾:

A B  C  D 
-------------------- 
4 blah 2  1 
2   3  0 
56 foo  3  1 

我可以通過將輸入數據框註冊爲臨時表來輕鬆完成此操作,然後輸入SQL查詢。

但我真的很想知道如何用Scala方法做到這一點,而不必在Scala中輸入SQL查詢。我試過.withColumn,但我無法做到我想做的。

回答

47

嘗試withColumn與功能when如下:

val sqlContext = new SQLContext(sc) 
import sqlContext.implicits._ // for `toDF` and $"" 
import org.apache.spark.sql.functions._ // for `when` 

val df = sc.parallelize(Seq((4, "blah", 2), (2, "", 3), (56, "foo", 3), (100, null, 5))) 
    .toDF("A", "B", "C") 

val newDf = df.withColumn("D", when($"B".isNull or $"B" === "", 0).otherwise(1)) 

newDf.show()顯示

+---+----+---+---+ 
| A| B| C| D| 
+---+----+---+---+ 
| 4|blah| 2| 1| 
| 2| | 3| 0| 
| 56| foo| 3| 1| 
|100|null| 5| 0| 
+---+----+---+---+ 

我加入了(100, null, 5)行用於測試isNull情況。

我試過這個代碼Spark 1.6.0,但作爲when代碼中的評論,它適用於1.4.0之後的版本。

+0

這正是我所需要的。我用'when'和'otherwise'嘗試了幾個不同的東西,但我想我得到了錯誤的確切格式。稍微偏離主題,但是你知道Spark如何處理列嗎?比如,如果我添加了〜20列,那麼使用.withColumn並保留一個數據幀或將其映射到RDD並將它們全部添加到映射中然後轉換回數據幀以保存到parquet會更快? – mcmcmc

+1

剛剛發現[this](http://stackoverflow.com/questions/33826495/spark-scala-2-10-tuple-limit)。我認爲UDF是我正在尋找的。 – mcmcmc

+0

UDF也是我在下面所說的... –

0

這樣的事情呢?

val newDF = df.filter($"B" === "").take(1) match { 
    case Array() => df 
    case _ => df.withColumn("D", $"B" === "") 
} 

使用take(1)應該有一個最低的命中

2

我的壞,我錯過了問題的一部分。

最好的,最乾淨的方法是使用UDF。 代碼中的解釋。

// create some example data...BY DataFrame 
// note, third record has an empty string 
case class Stuff(a:String,b:Int) 
val d= sc.parallelize(Seq(("a",1),("b",2), 
    ("",3) ,("d",4)).map { x => Stuff(x._1,x._2) }).toDF 

// now the good stuff. 
import org.apache.spark.sql.functions.udf 
// function that returns 0 is string empty 
val func = udf((s:String) => if(s.isEmpty) 0 else 1) 
// create new dataframe with added column named "notempty" 
val r = d.select($"a", $"b", func($"a").as("notempty")) 

    scala> r.show 
+---+---+--------+ 
| a| b|notempty| 
+---+---+--------+ 
| a| 1| 1111| 
| b| 2| 1111| 
| | 3|  0| 
| d| 4| 1111| 
+---+---+--------+ 
+0

這裏只有一個數據幀在播放。您可能需要重新閱讀問題 –