我有一个结构如下的数据框df:
输入
amount id
13000 1
30000 2
10000 3
5000 4
我想创建一个新列,该列基于列'amount'的分位数
预期输出:
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]))
答案 0 :(得分:6)
您可以使用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()
答案 1 :(得分:5)
如果您的数据整齐分布,则QuantileDiscretizer可以确定,但是当您指定numBuckets 时,它不会将列中的值范围拆分为相同大小的容器,而是通过某些启发式即可。你也无法选择垃圾箱的边界。
来自Spark ML的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