большое количество большого десятичного типа равно нулю при запросе - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть простой искровой код: я хочу запросить большое количество больших десятичных чисел

 test("SparkTest 0458") {
    val spark = SparkSession.builder().master("local").appName("SparkTest0456").getOrCreate()
    import spark.implicits._
    val data =
    (
      new java.math.BigDecimal("819021675302547012738064321"),
      new java.math.BigDecimal("819021675302547012738064321"),
      new java.math.BigDecimal("819021675302547012738064321")
    )

    val df = spark.createDataset(Seq(data)).toDF("a", "b", "c")
    df.show(truncate = false)
  }

Но он показывает 3 нуля

+----+----+----+
|a   |b   |c   |
+----+----+----+
|null|null|null|
+----+----+----+

Я бы спросил, что здесь не такспасибо

1 Ответ

0 голосов
/ 28 февраля 2019

Источником проблемы является механизм вывода схемы для десятичных типов.Поскольку ни масштаб, ни точность не являются частью сигнатуры типа, Spark предполагает, что входные данные равны decimal(38, 18):

df.printSchema
root
 |-- a: decimal(38,18) (nullable = true)
 |-- b: decimal(38,18) (nullable = true)
 |-- c: decimal(38,18) (nullable = true)

Это означает, что вы можете хранить не более 20 цифр перед десятичной точкой, а числаВы используете, есть 26 цифр.

Насколько я знаю, не существует обходного пути, который работает непосредственно с отражением, но есть возможность преобразовать данные в Row объекты и предоставить схему явно.Например, с промежуточным RDD

import org.apache.spark.sql.types._
import org.apache.spark.sql.Row
import java.math.BigDecimal

val schema = StructType(
  Seq("a", "b", "c") map (c => StructField(c, DecimalType(38, 0)))
)

spark.createDataFrame(
  sc.parallelize(Seq(data)) map(t => Row(t.productIterator.toSeq: _*)),
  schema
)

или сериализованным набором данных Kryo

import org.apache.spark.sql.{Encoder, Encoders}
import org.apache.spark.sql.catalyst.encoders.RowEncoder

spark.createDataset(Seq(data))(
  Encoders.kryo: Encoder[(BigDecimal, BigDecimal, BigDecimal)]
).map(t => Row(t.productIterator.toSeq: _*))(RowEncoder(schema))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...