Источником проблемы является механизм вывода схемы для десятичных типов.Поскольку ни масштаб, ни точность не являются частью сигнатуры типа, 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))