2017-04-26 36 views
1

我有一個數據幀DF與結構,像這樣創建一個列箱:如何在數據幀

輸入

amount id 
13000 1 
30000 2 
10000 3 
5000 4 

我要製作的基礎上,一個新的列

amount id amount_bin 
13000 1 10000 
30000 2 15000 
10000 3 10000 
5000 4 5000 
:的列 '量'

的預期輸出位數

假設品質0.25,0.5和0.75的5000,10000和15000分別

我知道該怎麼R中做到這一點:

quantile <- quantile(df$amount, probs = c(0, 0.25, 0.50, 0.75, 1.0), na.rm = TRUE, 
        names = FALSE) 

df$amount_bin <- cut(df$amount, breaks = quantile, include.lowest = TRUE, 
        labels = c(quantile[2], quantile[3], quantile[4], quantile[5])) 

回答

3

您可以使用QuantileDiscretizer從ML庫。

基於擬合的分位數創建桶:

import org.apache.spark.ml.feature.QuantileDiscretizer 

val data = Array((13000, 1), (30000, 2), (10000, 3), (5000, 4)) 
val df = spark.createDataFrame(data).toDF("amount", "id") 

val discretizer = new QuantileDiscretizer() 
    .setInputCol("amount") 
    .setOutputCol("result") 
    .setNumBuckets(4) 

val result = discretizer.fit(df).transform(df) 
result.show() 
+0

哇什麼巧妙的解決辦法!非常感謝這個!!!!! –

+0

它花了我最好的複製/粘貼工作:) – ImDarrenG

0

的QuantileDiscretizer工作OK如果你的數據是整齊地分佈,但是當你指定numBuckets 並不在列拆分值的範圍爲同樣大小的箱子,而是由一些啓發式。你也不能選擇垃圾桶的邊界。

從星火毫升Bucketizer但是確實有這些特點:

import org.apache.spark.ml.feature.Bucketizer 

val data = Array(0.99, 0.64, 0.39, 0.44, 0.15, 0.05, 0.30, 0.31, 0.22, 0.45, 0.52, 0.26) 
val df = spark.createDataFrame(data.map(Tuple1.apply)).toDF("continuousFeature") 

val bucketizer = new Bucketizer() 
    .setInputCol("continuousFeature") 
    .setOutputCol("discretizedFeature") 
    .setSplits(Array(0.0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.0)) 

    // the array of split values are the binning boundaries 

val binnedData = bucketizer.transform(df) 

binnedData.show 

+-----------------+------------------+ 
|continuousFeature|discretizedFeature| 
+-----------------+------------------+ 
|    0.99|    9.0| 
|    0.64|    6.0| 
|    0.39|    3.0| 
|    0.44|    4.0| 
|    0.15|    1.0| 
|    0.05|    0.0| 
|    0.3|    3.0| 
|    0.31|    3.0| 
|    0.22|    2.0| 
|    0.45|    4.0| 
|    0.52|    5.0| 
|    0.26|    2.0| 
+-----------------+------------------+ 

我認爲這是更好。讓您對結果有更多的控制權。

請注意,您的拆分範圍需要包含輸入列中的所有值,否則您將必須使用setHandleInvalid方法設置處理無效輸入值的規則。

您不需要像本示例中那樣指定有規律間隔的垃圾箱。

Scaladoc https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.ml.feature.Bucketizer

又如 https://github.com/apache/spark/blob/master/examples/src/main/scala/org/apache/spark/examples/ml/BucketizerExample.scala