我想創建一個具有案例類模式的行來測試我的一個地圖函數。我能想到這樣做的最直接的方法是:如何使用Spark-Scala中定義的模式創建行?
import org.apache.spark.sql.Row
case class MyCaseClass(foo: String, bar: Option[String])
def buildRowWithSchema(record: MyCaseClass): Row = {
sparkSession.createDataFrame(Seq(record)).collect.head
}
然而,這似乎是一個很大的開銷,只是得到一個單列的,所以我看着我怎麼能直接創建一排的模式。這導致我:
import org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema
import org.apache.spark.sql.{Encoders, Row}
def buildRowWithSchemaV2(record: MyCaseClass): Row = {
val recordValues: Array[Any] = record.getClass.getDeclaredFields.map((field) => {
field.setAccessible(true)
field.get(record)
})
new GenericRowWithSchema(recordValues, Encoders.product[MyCaseClass].schema)
}
不幸的是,第二個版本返回的行與第一行不同。第一個版本中的選項字段被縮減爲原始值,而它們仍然是第二個版本中的選項。另外,第二個版本相當笨拙。
有沒有更好的方法來做到這一點?
'take(1)'雖然比'collect.head'更高效,但沒有多大區別。我相信OP想要完全跳過RDD的創建。 –
@HristoIliev,我只是爲了驗證/顯示'dataframe'或'dataset'是'schema'的'Row'的集合。 –
但是OP需要一個'Row',而不是'DataSet'或'DataFrame'。現在,我不太清楚爲什麼,因爲他可以使用單個元素輕鬆測試分佈式集合上的映射函數。 –