在Scala API中对多个列进行过滤的相关语法是什么?如果我想做这样的事情:
dataFrame.filter($"col01" === "something" && $"col02" === "something else")
Run Code Online (Sandbox Code Playgroud)
要么
dataFrame.filter($"col01" === "something" || $"col02" === "something else")
Run Code Online (Sandbox Code Playgroud)
编辑:
这就是我的原始代码.一切都以字符串形式出现.
df.select($"userID" as "user", $"itemID" as "item", $"quantity" cast("int"), $"price" cast("float"), $"discount" cast ("float"), sqlf.substring($"datetime", 0, 10) as "date", $"group")
.filter($"item" !== "" && $"group" !== "-1")
Run Code Online (Sandbox Code Playgroud) 上下文: 我有一个包含两列的数据框:标签和功能.
org.apache.spark.sql.DataFrame = [label: int, features: vector]
Run Code Online (Sandbox Code Playgroud)
其中features是使用VectorAssembler构建的数值类型的mllib.linalg.VectorUDT.
问题: 有没有办法为特征向量分配模式?我想跟踪每个功能的名称.
到目前为止尝试过:
val defaultAttr = NumericAttribute.defaultAttr
val attrs = Array("feat1", "feat2", "feat3").map(defaultAttr.withName)
val attrGroup = new AttributeGroup("userFeatures", attrs.asInstanceOf[Array[Attribute]])
Run Code Online (Sandbox Code Playgroud)
scala> attrGroup.toMetadata
res197: org.apache.spark.sql.types.Metadata = {"ml_attr":{"attrs":{"numeric":[{"idx":0,"name":"f1"},{"idx":1,"name":"f2"},{"idx":2,"name":"f3"}]},"num_attrs":3}}
Run Code Online (Sandbox Code Playgroud)
但不确定如何将其应用于现有数据框.
语境:
我有一个Spark ML管道,它包含一个VectorAssembler,StringIndexer和一个DecisionTreeClassifier.使用此管道,我能够成功地拟合模型并转换我的数据框.我想存储此模型以供将来使用,但我不断收到以下错误:
Pipeline write will fail on this Pipeline because it contains a stage which does not implement Writable.
Non-Writable stage: dtc_9c04161ed2d1 of type class org.apache.spark.ml.classification.DecisionTreeClassificationModel
Run Code Online (Sandbox Code Playgroud)
我尝试过的:
val pipeline = new Pipeline().setStages(Array(assembler, labelIndexer, dt))
val model = pipeline.fit(dfIndexed)
model.write.overwrite().save("test/model/pipeline")
Run Code Online (Sandbox Code Playgroud)
当我删除分类器(即dt)时,这可以正常工作.有没有一种方法可以保存DecisionTreeClassifier模型?
我的数据包含一些索引的分类值,我必须将它们映射回原始形式(我知道这需要使用IndexToString).我正在使用Spark 1.6.
上下文:我有一个数据框,其中所有分类值都已使用StringIndexer编制索引.
val categoricalColumns = df.schema.collect { case StructField(name, StringType, nullable, meta) => name }
val categoryIndexers = categoricalColumns.map {
col => new StringIndexer().setInputCol(col).setOutputCol(s"${col}Indexed")
}
Run Code Online (Sandbox Code Playgroud)
然后我使用VectorAssembler来矢量化所有要素列(包括索引的分类列).
val assembler = new VectorAssembler()
.setInputCols(dfIndexed.columns.diff(List("label") ++ categoricalColumns))
.setOutputCol("features")
Run Code Online (Sandbox Code Playgroud)
应用分类器和一些额外的步骤后,我最终得到一个具有标签,功能和预测的数据框.我想将我的特征向量扩展为单独的列,以便将索引值转换回原始的String形式.
val categoryConverters = categoricalColumns.zip(categoryIndexers).map {
colAndIndexer => new IndexToString().setInputCol(s"${colAndIndexer._1}Indexed").setOutputCol(colAndIndexer._1).setLabels(colAndIndexer._2.fit(df).labels)
}
Run Code Online (Sandbox Code Playgroud)
问题:是否有一种简单的方法可以做到这一点,或者是以某种方式将预测列附加到测试数据框的最佳方法?
我尝试过的:
val featureSlicers = categoricalColumns.map {
col => new VectorSlicer().setInputCol("features").setOutputCol(s"${col}Indexed").setNames(Array(s"${col}Indexed"))
}
Run Code Online (Sandbox Code Playgroud)
应用这个给了我想要的列,但是它们是Vector形式的(因为它意味着这样做)而不是Double类型.
编辑: 所需的输出是原始数据框(即分类特征为字符串而非索引),附加列指示预测标签(在我的情况下为0或1).
例如,假设我的分类器的输出看起来像这样:
+-----+---------+----------+
|label| features|prediction|
+-----+---------+----------+
| 1.0|[0.0,3.0]| 1.0|
+-----+---------+----------+
Run Code Online (Sandbox Code Playgroud)
通过在每个功能上应用VectorSlicer,我会得到:
+-----+---------+----------+-------------+-------------+
|label| features|prediction|statusIndexed|artistIndexed|
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| …Run Code Online (Sandbox Code Playgroud)