Конечно, вы можете сопоставить объект Row с классом case. Предположим, ваш SchemaType имеет много полей, и вы хотите сопоставить некоторые из них с вашим классом case. Если у вас нет нулевых полей, вы можете просто сделать:
case class MyClass(a: Long, b: String, c: Int, d: String, e: String)
dataframe.map {
case Row(a: java.math.BigDecimal,
b: String,
c: Int,
_: String,
_: java.sql.Date,
e: java.sql.Date,
_: java.sql.Timestamp,
_: java.sql.Timestamp,
_: java.math.BigDecimal,
_: String) => MyClass(a = a.longValue(), b = b, c = c, d = d.toString, e = e.toString)
}
Этот подход не работает в случае нулевых значений, а также требует, чтобы вы явно определяли тип каждого отдельного поля. Если вам нужно обрабатывать нулевые значения, вам нужно либо отбросить все строки, содержащие нулевые значения, выполнив
dataframe.na.drop()
Это приведет к удалению записей, даже если пустые поля не те, которые используются в вашем сопоставлении с шаблоном для вашего класса case. Или, если вы хотите справиться с этим, вы можете превратить объект Row в список, а затем использовать шаблон параметров:
case class MyClass(a: Long, b: String, c: Option[Int], d: String, e: String)
dataframe.map(_.toSeq.toList match {
case List(a: java.math.BigDecimal,
b: String,
c: Int,
_: String,
_: java.sql.Date,
e: java.sql.Date,
_: java.sql.Timestamp,
_: java.sql.Timestamp,
_: java.math.BigDecimal,
_: String) => MyClass(
a = a.longValue(), b = b, c = Option(c), d = d.toString, e = e.toString)
}
Проверьте этот проект на github Sparkz (), который вскоре представит множество библиотек для упрощения API-интерфейсов Spark и DataFrame и сделает их более ориентированными на функциональное программирование.
person
Gianmario Spacagna
schedule
02.11.2015
null
s. Может быть, макросы (если у вас много case-классов)? - person Gábor Bakos   schedule 27.01.2015