2017-07-17 58 views
0

例如:如何在Spark Dataframe中的列之间做一些复杂的计算?

val calresult1 = indexedresult.withColumn("_4", lit(1)) 
calresult1.show() 
+---+---+------------------+---+ 
| _1| _2|    _3| _4| 
+---+---+------------------+---+ 
| 5| 2|    5.0| 1| 
| 5| 0|0.5555555555555554| 1| 
| 4| 0| 3.222222222222222| 1| 
| 3| 5|    1.0| 1| 
...... 

我可以用做一些简单的计算+, - ,*,/:

val calresult2 = calresult1.withColumn("_5", calresult1.col("_4")/(calresult1.col("_3"))).select("_1","_2","_5") 
calresult2.show() 
+---+---+------------------+ 
| _1| _2|    _5| 
+---+---+------------------+ 
| 5| 2|    0.2| 
| 5| 0|1.8000000000000007| 
| 4| 0|    1.0| 
...... 

但不能使用战俘和开方:

val calresult2 = calresult1.withColumn("_5", pow(calresult1.col("_4")+(calresult1.col("_3")))).select("_1","_2","_5") 
calresult2.show() 

错误:

Error:(414, 53) could not find implicit value for parameter impl: breeze.numerics.pow.Impl[org.apache.spark.sql.Column,VR] 
val calresult2 = calresult1.withColumn("_5", pow(calresult1.col("_4")+(calresult1.col("_3")))).select("_1","_2","_5") 
               ^

如何实现复杂的公式?

回答

0

pow()需要2个Double类型的参数。我相信你错过了第二个参数:

pow(calresult1.col("_4")+(calresult1.col("_3"))) 

提供了第二个参数,如下面的例子就可以解决问题:

import org.apache.spark.sql.functions._ 

val calresult2 = calresult1.withColumn(
    "_5", pow(calresult1.col("_4")+(calresult1.col("_3")), 2.0) 
).select(
    "_1","_2","_5" 
).show 

+---+---+------------------+ 
| _1| _2|    _5| 
+---+---+------------------+ 
| 5| 2|    36.0| 
| 5| 0|2.4197530864197523| 
| 4| 0|17.827160493827154| 
| 3| 5|    4.0| 
+---+---+------------------+ 
+0

如何控制精度?例如:将2.4197530864197523转换为2.41975。 –

+0

只需使用'round()'作为第二个参数即可。使用前面的例子,'round(pow(calresult1.col(“_ 4”)+(calresult1.col(“_ 3”)),2.0),5)'会给出想要的精度。 –

0

只需使用内置功能:

import org.apache.spark.sql.functions.{pow, sqrt} 

,你会好的。

一般来说,您可以使用UserDefinedFunctions但这里并不需要。

相关问题