我是斯卡拉的新手。请耐心等候。
我有这个代码。
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的快照。在这一点上,我只想忽略转换错误。 任何想法为什么会这样?
答案 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创建相关的问题,而不是转换问题。