2015-09-09 24 views
0

所以我寫的基礎上(即不工作)如何在我的數據幀平均每FloatType柱像這樣:將集合功能對某些類型的每一列

val descript = df.dtypes 

    var decimalArr = new ListBuffer[String]() 
    for(i <- 0 to (descript.length - 1)) { 
    if(descript(i)._2 == "FloatType") { 
     decimalArr += descript(i)._1 
    } 
    } 

    //Build Statsitical Arguments for DataFrame Pass 
    var averageList = new ListBuffer[String]() 
    for(i <- 0 to (decimalArr.length - 1)){ 
    averageList += "avg(" + '"' + decimalArr(i) + '"' + ")" 
    } 

    //sample statsitical call 
    val sampAvg = df.agg(averageList).show 

即得到由averageList生產的例子是:

ListBuffer(avg("offer_id"), avg("decision_id"), avg("offer_type_cd"), avg("promo_id"), avg("pymt_method_type_cd"), avg("cs_result_id"), avg("cs_result_usage_type_cd"), avg("rate_index_type_cd"), avg("sub_product_id")) 

將澄清的問題是,VAL sampAvg = df.agg(averageList).show不允許listBuffer作爲輸入。所以即使把它.toString不工作,它想要org.apache.spark.sql.Column *。有沒有人知道我可以用我嘗試的方式做點什麼。

旁註我在星火1.3

+0

您是否嘗試過在平均列表中使用sc.parallelize,然後使用.toDF()函數? – Niemand

回答

3

可以先建總表達式列表

import org.apache.spark.sql.functions.{col, avg, lit} 

val exprs = df.dtypes 
    .filter(_._2 == "DoubleType") 
    .map(ct => avg(col(ct._1))).toList 

,要麼模式匹配

exprs match { 
    case h::t => df.agg(h, t:_*) 
    case _ => sqlContext.emptyDataFrame 
} 

,或者使用虛擬列

df.agg(lit(1).alias("_dummy"), exprs: _*).drop("_dummy") 

如果你想使用多種功能,你可以flatMap明示:

import org.apache.spark.sql.Column 
import org.apache.spark.sql.functions.{avg, min, max} 

val funs: List[(String => Column)] = List(min, max, avg) 

val exprs: Array[Column] = df.dtypes 
    .filter(_._2 == "DoubleType") 
    .flatMap(ct => funs.map(fun => fun(ct._1))) 

或使用理解:

val exprs: Array[Column] = for { 
    cname <- df.dtypes.filter(_._2 == "DoubleType").map(_._1) 
    fun <- funs 
} yield fun(cname) 

,如果你想使用模式匹配的方法轉換到exprsList

+0

問題爲什麼會val exprs = df.dtypes .filter(_._ 2 ==「DoubleType」) .map(ct => avg(col(ct._1)))。toList work但如果我將其分解爲val exprs = df.dtypes.filter(_._ 2 ==「DoubleType」)和val avg = exprs.map(ct => avg(col(ct._1)))。toList will not?我打算做最小和最大,所以我想分割映射併合併成一個大集合,如果這是有道理的。 – theMadKing

+0

因爲如果你使用'val avg = exprs.map(ct => avg(col(ct._1)))。toList',你會得到一個遞歸調用(注意LHS和RHS上的'avg'),並且它與編譯器重要時刻。 – zero323

+0

@ zero323感謝您的詳細解釋。有什麼辦法可以在所有數字列上應用聚合,比如'IntegerType','Doubletype'。 – analyticalpicasso

相關問題