2016-08-19 39 views
2

我有一個數據幀,其模式是我下面的字段值:如何在數據幀劃分上階

root 
|-- school: string (nullable = true) 
|-- questionName: string (nullable = true) 
|-- difficultyValue: double (nullable = true) 

的數據是這樣的:

school | questionName | difficultyValue 
school1 | q1   | 0.32 
school1 | q2   | 0.13 
school1 | q3   | 0.58 
school1 | q4   | 0.67 
school1 | q5   | 0.59 
school1 | q6   | 0.43 
school1 | q7   | 0.31 
school1 | q8   | 0.15 
school1 | q9   | 0.21 
school1 | q10   | 0.92 

但現在我想分區場「難度值」根據其值,並將該數據幀轉換爲以下模式的新數據幀:

root 
|-- school: string (nullable = true) 
|-- difficulty1: double (nullable = true) 
|-- difficulty2: double (nullable = true) 
|-- difficulty3: double (nullable = true) 
|-- difficulty4: double (nullable = true) 
|-- difficulty5: double (nullable = true) 

a第二新數據表是在這裏:

school | difficulty1 | difficulty2 | difficulty3 | difficulty4 | difficulty5 
school1 | 2   | 3   | 3   | 1   |1 

的字段「difficulty1」的值是「difficultyValue」 < 0.2的數;

「難度2」字段的值是「難度值」< 0.4和「難度值」> = 0.2的值;

「難度3」字段的值是「難度值」< 0.6和「難度值」> = 0.4的值;

「難度4」字段的值是「難度值」< 0.8和「難度值」> = 0.6的值;

字段「難度5」的值是「難度值」< 1.0和「難度值」> = 0.8的值;

我不知道如何改變它,我該怎麼辦?

回答

1
// First create a test data frame with the schema of your given source. 
val df = { 
    import org.apache.spark.sql._ 
    import org.apache.spark.sql.types._ 
    import scala.collection.JavaConverters._ 

    val simpleSchema = StructType(
     StructField("school", StringType, false) :: 
     StructField("questionName", StringType, false) :: 
     StructField("difficultyValue", DoubleType) :: Nil) 

    val data = List(
     Row("school1", "q1", 0.32), 
     Row("school1", "q2", 0.45), 
     Row("school1", "q3", 0.22), 
     Row("school1", "q4", 0.12), 
     Row("school2", "q1", 0.32), 
     Row("school2", "q2", 0.42), 
     Row("school2", "q3", 0.52), 
     Row("school2", "q4", 0.62) 
    )  

    spark.createDataFrame(data.asJava, simpleSchema) 
} 
// Add a new column that is the 1-5 category. 
val df2 = df.withColumn("difficultyCat", floor(col("difficultyValue").multiply(5.0)) + 1) 
// groupBy and pivot to get the final view that you want. 
// Here, we know 1-5 values before-hand, if you don't you can omit with performance cost. 
val df3 = df2.groupBy("school").pivot("difficultyCat", Seq(1, 2, 3, 4, 5)).count() 

df3.show() 
+0

克萊嗨,你的答案是偉大的,因爲我只有五列,所以我可以指定disticnt值列表轉動上,就這樣'''VAL DF3 = df2.groupBy(「schoolID」 ).pivot(「difficultyCat」,Seq(1,2,3,4,5))。count()''',非常感謝。 – StrongYoung

+0

是的,你是對的。如果您事先知道可能的值,就像我們在這種情況下所做的那樣,爲了性能原因,您應該將它們傳遞給pivot函數。我更新了答案中的代碼。 – clay

0

以下功能:

def valueToIndex(v: Double): Int = scala.math.ceil(v*5).toInt 

將決定你在難度值所需的指標,因爲你只是想5個均勻箱。您可以使用此函數使用withColumnudf創建新派生列,然後可以使用pivot來生成每個索引的行數。