2017-04-26 11 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 

予想される出力列 '量' は分位

私はRでこれを行う方法を知って

それぞれ0.25、0.5及び0.75は5000、10000と15000です資質を想定します。

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

あなたはMLライブラリからQuantileDiscretizerを使用することができます。

フィット分位数に基づいてバケットを作成します。

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は、あなたのデータがきちんと分散されている場合、しかし、あなたはnumBuckets を指定すると、それは均等に列の値の範囲を分割しないOKの作品むしろ何らかのヒューリスティックなによって、ビンの境界を選択することもできません。私は非常に良くあると思い

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| 
+-----------------+------------------+ 

を:

スパークMLからBucketizerは、しかし、これらの機能を持っていません。あなたの結果をより詳細に制御できます。

スプリットの範囲には入力列のすべての値が含まれている必要があります。それ以外の場合は、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

関連する問題