【发布时间】:2018-07-24 20:16:19
【问题描述】:
我有一个包含两列的数据框,
+---+-------+
| id| fruit|
+---+-------+
| 0| apple|
| 1| banana|
| 2|coconut|
| 1| banana|
| 2|coconut|
+---+-------+
我还有一个包含所有项目的通用列表,
fruitList: Seq[String] = WrappedArray(apple, coconut, banana)
现在我想在数据框中创建一个新列,其中包含 1、0 的数组,其中 1 表示该项目存在,如果该行不存在该项目,则为 0。
期望的输出
+---+-----------+
| id| fruitlist|
+---+-----------+
| 0| [1,0,0] |
| 1| [0,1,0] |
| 2|[0,0,1] |
| 1| [0,1,0] |
| 2|[0,0,1] |
+---+-----------+
这是我尝试过的,
import org.apache.spark.ml.feature.{OneHotEncoder, StringIndexer}
val df = spark.createDataFrame(Seq(
(0, "apple"),
(1, "banana"),
(2, "coconut"),
(1, "banana"),
(2, "coconut")
)).toDF("id", "fruit")
df.show
import org.apache.spark.sql.functions._
val fruitList = df.select(collect_set("fruit")).first().getAs[Seq[String]](0)
print(fruitList)
我尝试使用 OneHotEncoder 解决这个问题,但转换为密集向量后的结果是这样的,这不是我需要的。
+---+-------+----------+-------------+---------+
| id| fruit|fruitIndex| fruitVec| vd|
+---+-------+----------+-------------+---------+
| 0| apple| 2.0| (2,[],[])|[0.0,0.0]|
| 1| banana| 1.0|(2,[1],[1.0])|[0.0,1.0]|
| 2|coconut| 0.0|(2,[0],[1.0])|[1.0,0.0]|
| 1| banana| 1.0|(2,[1],[1.0])|[0.0,1.0]|
| 2|coconut| 0.0|(2,[0],[1.0])|[1.0,0.0]|
+---+-------+----------+-------------+---------+
【问题讨论】:
-
我不确定我是否理解你的最后一句话。您显示的最后一个表格中的结果是稀疏的。
-
@eliasah,我已经用正确的密集向量表示编辑了这个问题。
-
您的向量长度为 2,因为您在 OneHotEncoder 上使用了默认参数
dropLast=True。但无论如何,它不会保持您想要的顺序(因为 StringIndexer 按出现顺序排列项目)。使用@Ramesh Maharjan 回答 -
@Arius,谢谢你的提示,设置 encoder.setDropLast(false) 将显示完整的向量元素。onehotestimator 会保持顺序吗?
-
@Masterbuilder 是的 OneHotEncoder 会,但之前的 StringIndexer 会破坏它。
标签: apache-spark apache-spark-mllib apache-spark-ml