Вместо этого выборка DataFrame в класс Case приводит к чтению Tuple1 - PullRequest
0 голосов
/ 21 января 2019

Учитывая case class:

case class ScoringSummary(MatchMethod: String="", 
TP: Double=0, 
FP: Double=0, 
Precision: Double=0, 
Recall: Double=0, 
F1: Double=0)

Мы записываем сводные записи в виде:

summaryDf.write.parquet(path)

Позже мы (попытка) считываем файл паркета в новый кадр данных:

implicit val generalRowEncoder: Encoder[ScoringSummary] = 
    org.apache.spark.sql.Encoders.kryo[ScoringSummary]
val summaryDf = spark.read.parquet(path).as[ScoringSummary]

Но это не удается - по какой-то причине spark считает, что содержимое данных было Tuple1 вместо ScoringSummary:

Try to map struct<MatchMethod:string,TP:double,FP:double,Precision:double,
Recall:double,F1:double> to Tuple1, 
but failed as the number of fields does not line up.;
    at org.apache.spark.sql.catalyst.analysis.Analyzer$ResolveDeserializer$
.org$apache$spark$sql$catalyst$analysis$Analyzer$
ResolveDeserializer$$fail(Analyzer.scala:2168)

Какой шаг / настройка отсутствует/ неверный для правильного перевода?

1 Ответ

0 голосов
/ 21 января 2019

Используйте import spark.implicits._ вместо регистрации кодера

Я забыл, что требуется импортировать spark.implicits. Неправильный подход заключался в добавлении Encoder: т.е. , а не , включая следующую строку

implicit val generalRowEncoder: Encoder[ScoringSummary] = 
org.apache.spark.sql.Encoders.kryo[ScoringSummary]   // Do NOT add this Encoder

Вот ошибка при удалении строки Encoder

Ошибка: (59, 113) Невозможно найти кодировщик для типа, сохраненного в наборе данных. Примитивные типы (Int, String и т. Д.) И Типы продуктов (классы дел) поддерживаются за счет импорта spark.implicits._ Поддержка сериализации другие типы будут добавлены в будущих выпусках. val summaryDf = ParquetLoader.loadParquet (sparkEnv, res.state.dfs (ScoringSummaryTag) .copy (df = None)). df.get.as [ScoringSummary]

Вместо этого следует добавить следующий код

import spark.implicits._

И тогда работает тот же код:

val summaryDf = spark.read.parquet(path).as[ScoringSummary]

enter image description here

Кроме того: кодировщики не требуются для case class 's или primitive типов: и выше равно a case class. kryo становится удобным для сложных типов объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...