【问题标题】:Error when running a query involving ROUND function in spark sql在 spark sql 中运行涉及 ROUND 函数的查询时出错
【发布时间】:2018-10-08 15:57:37
【问题描述】:

我正在尝试在 pyspark 中通过将表格的一列四舍五入到同一表格的另一列在每一行中指定的精度来获得一个新列,例如,来自下表:

+--------+--------+
|    Data|Rounding|
+--------+--------+
|3.141592|       3|
|0.577215|       1|
+--------+--------+

我应该可以得到如下结果:

+--------+--------+--------------+
|    Data|Rounding|Rounded_Column|
+--------+--------+--------------+
|3.141592|       3|         3.142|
|0.577215|       1|           0.6|
+--------+--------+--------------+

特别是我尝试了以下代码:

import pandas as pd
from pyspark.sql import SparkSession
from pyspark.sql.types import (
  StructType, StructField, FloatType, LongType, 
  IntegerType
)

pdDF = pd.DataFrame(columns=["Data", "Rounding"], data=[[3.141592, 3], 
   [0.577215, 1]])

mySchema = StructType([ StructField("Data", FloatType(), True), 
StructField("Rounding", IntegerType(), True)])

spark = (SparkSession.builder
    .master("local")
    .appName("column rounding")
    .getOrCreate())

df = spark.createDataFrame(pdDF,schema=mySchema)

df.show()

df.createOrReplaceTempView("df_table")


df_rounded = spark.sql("SELECT Data, Rounding, ROUND(Data, Rounding) AS Rounded_Column FROM df_table")

df_rounded .show()

但我收到以下错误:

raise AnalysisException(s.split(': ', 1)[1], stackTrace)
pyspark.sql.utils.AnalysisException: u"cannot resolve 'round(df_table.`Data`, df_table.`Rounding`)' due to data type mismatch: Only foldable Expression is allowed for scale arguments; line 1 pos 23;\n'Project [Data#0, Rounding#1, round(Data#0, Rounding#1) AS Rounded_Column#12]\n+- SubqueryAlias df_table\n   +- LogicalRDD [Data#0, Rounding#1], false\n"

任何帮助将不胜感激:)

【问题讨论】:

    标签: apache-spark apache-spark-sql pyspark-sql


    【解决方案1】:

    使用 spark sql ,催化剂会在您的运行中抛出以下错误 - Only foldable Expression is allowed for scale arguments

    @param scale new scale to be round to, this should be a constant int at runtime

    ROUND 只期望一个字面量作为刻度。您可以尝试编写自定义代码而不是 spark-sql 方式。

    编辑:

    使用 UDF,

    val df = Seq(
      (3.141592,3),
      (0.577215,1)).toDF("Data","Rounding")
    
    df.show()
    df.createOrReplaceTempView("df_table")
    
    import org.apache.spark.sql.functions._
    def RoundUDF(customvalue:Double, customscale:Int):Double = BigDecimal(customvalue).setScale(customscale, BigDecimal.RoundingMode.HALF_UP).toDouble
    spark.udf.register("RoundUDF", RoundUDF(_:Double,_:Int):Double)
    
    val df_rounded = spark.sql("select Data, Rounding, RoundUDF(Data, Rounding) as Rounded_Column from df_table")
    df_rounded.show()
    

    输入:

        +--------+--------+
        |    Data|Rounding|
        +--------+--------+
        |3.141592|       3|
        |0.577215|       1|
        +--------+--------+
    

    输出:

    +--------+--------+--------------+
    |    Data|Rounding|Rounded_Column|
    +--------+--------+--------------+
    |3.141592|       3|         3.142|
    |0.577215|       1|           0.6|
    +--------+--------+--------------+
    

    【讨论】:

    • 我应该尝试哪种自定义代码/您会建议吗?
    • 我对我的帖子进行了编辑,可以看到基于 UDF 的方法适合您。
    • 天哪!非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 2016-07-26
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 2021-12-01
    • 2015-05-12
    相关资源
    最近更新 更多