Spark Java使用数学运算获取与最大截止值的比例价值。

3

我对Spark的概念理解得很好,但仍在处理表达式的具体语法选项。我正在使用Java 17和Spark 3.3.0。

我有一个列名为foo的表格,它的值不应该比30高太多。 我想添加一个列,该列是使用foo30作比例计算,即用foo的值除以30并使其规范化为0.0 <= proportion <= 1.0. 最后提到,foo是十进制类型,用BigDecimal表示了Java中的形式。

我可以使用以下Java代码来进行以上计算:

BigDecimal maxVal = new BigDecimal(30); 
BigDecimal proportion = foo.max(maxVal).divide(maxVal);

(或者我可以先将其除以maxVal,然后取结果和1.0的最大值,尽管上述第一种方法可能更有效率且语义更直接。)
在Spark中,我应该如何最好地做到这一点?以下方法似乎有效,并且可以让我完成大部分工作:
BigDecimal maxVal = new BigDecimal(30);
df = df.withColumn("proportion", col("foo").divide(maxVal));

但是关于max()的部分,我怎么让它在30处截断值呢? 我只能立即找到的一个“max”函数是Spark SQL的MAX()聚合函数。

1个回答

1

虽然 minmax 是聚合函数,可以在一组行上工作,但函数 leastgreatest 可以比较行内或与常量值的值。

import static org.apache.spark.sql.functions.*;

Dataset<Row> df = ...
BigDecimal maxVal=new BigDecimal(30);
df.withColumn("proportion", greatest(col("value"), lit(maxVal)).divide(maxVal)).show();

输出:

+-----+----------+
|value|proportion|
+-----+----------+
|    1|  1.000000|
|   10|  1.000000|
|   20|  1.000000|
|   30|  1.000000|
|   31|  1.033333|
|   40|  1.333333|
+-----+----------+

如果值应该限制在maxValue,则应该使用least而不是greatest(这相当于在非Spark代码中使用BigDecimal.min):
df.withColumn("proportion", least(col("value"), lit(maxVal)).divide(maxVal)).show();

现在的输出:

+-----+----------+
|value|proportion|
+-----+----------+
|    1|  0.033333|
|   10|  0.333333|
|   20|  0.666667|
|   30|  1.000000|
|   31|  1.000000|
|   40|  1.000000|
+-----+----------+

哦,太好了!这就是关于知道要查找什么名称的全部内容。谢谢。 - Garret Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接