我试图将DataFrame
(名为:df
)的单个列的不同值放入与列的数据类型匹配的数组中。这是我尝试过的,但它不起作用:
def distinctValues[T: ClassTag](column: String): Array[T] = {
df.select(df(column)).distinct.map {
case Row(s: T) => s
}.collect
}
该方法位于隐式类中,因此调用df.distinctValues("some_col")
会给我:
scala.MatchError: [ABCD] (of class org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema)
是否有一种优雅的方式来实现我想要的类型安全?
我在Spark 1.4.1上。
答案 0 :(得分:3)
问题在于您使用模式匹配而不是getAs
方法:
implicit final class DataFrameOps(val df: DataFrame) {
def distinctValues[T: ClassTag](column: String): Array[T] = {
df.select(column).distinct().map(_.getAs[T](column)).collect()
}
}
用法:
val ageArray: Array[Int] = df.distinctValues("age")
or
val ageArray = df.distinctValues[Int]("age")
答案 1 :(得分:1)
从1.4.0开始,Spark有dropDuplicates
方法通过列序列(或所有列,如果没有指定)实现不同的方法:
//drop duplicates considering specified columns
val distinctDf = df.select($"column").dropDuplicates(Seq("column"))
//this should work too since df has one column after select
val distinctDf = df.select($"column").dropDuplicates()
//collect
def getValues[T](df: DataFrame, columnName: String) = {
df.map(_.getAs[T](columnName)).collect()
}
getValues[String](distinctDf, "column")