Большие отрицательные десятичные значения округляются в искровом фрейме данных с десятичным типом - PullRequest
0 голосов
/ 16 апреля 2020

Запрос помощи по нижеуказанному вопросу. Мы извлекаем данные из Oracle, используя искру, и один из типов данных столбца является числом (28,5), для меньших значений он работает нормально, но если большие отрицательные значения, данные усекаются, как -544205937126085.125 преобразуется в -544205937126085.100 , Я пытался в местном, но проблема, и это дает ту же проблему.

import org.apache.spark.sql.SparkSession

object DecimalIssue {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local")
      .appName("Decimal Issue")
      .getOrCreate()

    spark.sparkContext.setLogLevel("ERROR")

    import  spark.implicits._


    val df = Seq((1234,1234.50),
      (1234,-544205937126085.125 ),
        (1234,200.567),
      (1234,-200.567)
    ).toDF("smallvalue","bigvalue")


    val df2 = df.select($"smallvalue",$"bigvalue".cast("decimal(28,5)"))

    df2.show(10,false)
    df2.printSchema()
  }

}

и вывод кода выше.

+----------+----------------------+
|smallvalue|bigvalue              |
+----------+----------------------+
|1234      |1234.50000            |
|1234      |-544205937126085.10000|
|1234      |200.56700             |
|1234      |-200.56700            |
+----------+----------------------+

root
 |-- smallvalue: integer (nullable = false)
 |-- bigvalue: decimal(28,5) (nullable = true)


В идеале я ищу вывод

+----------+----------------------+
|smallvalue|bigvalue              |
+----------+----------------------+
|1234      |1234.50000            |
|1234      |-544205937126085.12500|
|1234      |200.56700             |
|1234      |-200.56700            |
+----------+----------------------+

root
 |-- smallvalue: integer (nullable = false)
 |-- bigvalue: decimal(28,5) (nullable = true)

РЕДАКТИРОВАТЬ: Даже положительные значения также дают усеченные результаты.

ДОБАВЛЕННЫЕ данные, такие как JSON СООБЩЕНИЕ

object DecimalIssue {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local")
      .appName("Decimal Issue")
      .getOrCreate()

    spark.sparkContext.setLogLevel("ERROR")

//    (1234, "1234.50"),
//    (1234, "544205937126085.125"),
//    (1234, "200.567"),
//    (1234, "-200.567")
    val customSchema = new StructType(Array(
  StructField("smallvalue",LongType,true),
  StructField("bigvalue",StringType,true)
))
    import spark.implicits._

    val data = "{\"smallvalue\":1234,\"bigvalue\":544205937126085.125}"
    val df = Seq( data
    ).toDF("data")

    val df1 = df.select(from_json($"data",customSchema).as("orig")).select("orig.*")

    df1.show(10,false)
    df1.printSchema()

    val  tryBigDecimal: String => BigDecimal = BigDecimal(_)
    val bigUDF = udf(tryBigDecimal)

    val bigDecimalUDF = udf(tryBigDecimal)
    val df2 = df1.select($"smallvalue", bigUDF($"bigvalue").cast("decimal(28,5)"))


    df2.show(10, false)
    df2.printSchema()
  }


}

Но дает те же результаты

Заранее спасибо.

1 Ответ

0 голосов
/ 16 апреля 2020

Теперь в файле. json числа читаются как десятичные значения с опцией ".option (" prefersDecimal ", true)"

file. json

{"smallvalue":1234,"bigvalue":544205937126085.125},
{"smallvalue":1224,"bigvalue":54420593712608534.12521},
{"smallvalue":2224,"bigvalue":5420593712608534.32521},
{"smallvalue":1114,"bigvalue":950420593712608534.521}

код

import org.apache.spark.sql.SparkSession
object DecimalIssue {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local")
      .enableHiveSupport()
      .appName("Decimal Issue")
      .getOrCreate()
    spark.sparkContext.setLogLevel("ERROR")
    val sqlContext = spark.sqlContext
    import org.apache.spark.sql.functions._

    val input = "/home/cloudera/files/tests/decimal.json"
    val data = sqlContext
      .read
      .option("prefersDecimal", true)
      .json(input)
    data.select(col("bigvalue").cast("decimal(28,5)"), col("smallvalue").cast("int")).show(truncate = false)
  }
}

и ожидаемый результат

root
 |-- bigvalue: decimal(23,5) (nullable = true)
 |-- smallvalue: long (nullable = true)

+------------------------+----------+
|bigvalue                |smallvalue|
+------------------------+----------+
|544205937126085.12500   |1234      |
|54420593712608534.12521 |1224      |
|5420593712608534.32521  |2224      |
|950420593712608534.52100|1114      |
+------------------------+----------+

Вы можете найти все опции в документации по искрам:

http://spark.apache.org/docs/2.3.0/api/scala/index.html#org. apache .spark. sql .DataFrameReader

Я надеюсь, что это может быть полезно или даст вам некоторые подсказки,

С уважением

...