创建数据框时出现scala火花转换错误

时间:2018-09-24 09:31:05

标签: scala apache-spark dataframe casting

我是斯卡拉的新手。请耐心等候。

我有这个代码。

import org.apache.spark.sql.{DataFrame, Dataset, SparkSession}
import org.apache.spark.ml.clustering.KMeans
import org.apache.spark.ml.evaluation._
import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.ml.evaluation.ClusteringEvaluator

// create spark session
implicit val spark = SparkSession.builder().appName("clustering").getOrCreate()

// read file
val fileName = """file:///some_location/head_sessions_sample.csv"""

// create DF from file
val df = spark.read.format("csv").option("header", "true").option("inferSchema", "true").load(fileName)

def inputKmeans(df: DataFrame,spark: SparkSession): DataFrame = {
    try {
      val a = df.select("id", "start_ts", "duration", "ip_dist").map(r => (r.getInt(0), Vectors.dense(r.getDouble(1), r.getDouble(2), r.getDouble(3)))).toDF("id", "features")
      a
    }
    catch {
      case e: java.lang.ClassCastException => spark.emptyDataFrame
   }
}


val t = inputKmeans(df).filter( _ != null )
t.foreach(r =>
            if (r.get(0) != null)
              println(r.get(0)))

目前,我想忽略我的转换错误。但是不知何故,我仍然有它们。

  

2018-09-24 11:26:22错误执行器:91-阶段任务0.0中的异常   4.0(TID 6)java.lang.ClassCastException:无法将java.lang.Long强制转换为java.lang.Double

我认为没有任何必要提供csv的快照。在这一点上,我只想忽略转换错误。 任何想法为什么会这样?

2 个答案:

答案 0 :(得分:0)

如评论中所述,问题是因为值不是Double类型。

val a = df.select("id", "start_ts", "duration", "ip_dist").map(r => (r.getInt(0), Vectors.dense(r.getDouble(1), r.getDouble(2), r.getDouble(3)))).toDF("id", "features")

强制转换为正确的数据类型,即长类型(您也可以使用Case类显式提供Schema并将该模式​​应用于DataFrame)。

或使用 VectorAssembler 将列转换为要素。这是更容易推荐的方法。

import org.apache.spark.ml.feature.VectorAssembler 
def inputKmeans(df: DataFrame,spark: SparkSession): DataFrame = {
  val assembler = new VectorAssembler().setInputCols(Array("start_ts", "duration", "ip_dist")).setOutputCol("features")
  val output = assembler.transform(df).select("id", "features")
  output
}

答案 1 :(得分:0)

我认为我发现了问题。 “尝试捕获”位于DF创建的级别,而不是转换的级别。结果,它捕获了与DF创建相关的问题,而不是转换问题。