我一直在尝试在Scala的Spark 2.3.0中对值数组进行编码。我尝试使用Spark OneHotEncoderEstimator
,它对于单个String
或Int
来说效果很好,但是我无法将其扩展为在数组上工作(我尝试的一种方法是{{1 }}该列-起作用了,但是后来我无法将其返回到数组中,相反,explode
仅给出了一个由一键编码的collect_set
数组。
我发现了这个问题:
One hot encoding in RDD in scala
我以此为基础来开发在数组上工作的函数。我修改了解决方案中发布的功能:
Vectors
对此:
def encode(x: String) = {
var encodeArray = Array.fill(21)(0)
encodeArray(indexed_user.get(x).get.toInt)=1
encodeArray}
我的def encodeSeq(x:Seq[String]) = {
var encodeArray = Array.fill(21)(0)
x.foreach(s => encodeArray(indexed.get(s).get.toInt)=1)
encodeArr}
是indexed
的地图。我已经在一个序列上测试了此功能,它返回了我期望的结果:
String -> Int
但是当申请val testSeq = Seq("a", "b")
encodeSeq(testSeq)
res97: Array[Int] = Array(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
时,我得到的是RDD
,而不是预期的RDD[Ints]
:
RDD[Array]
在这里,val encoded = unencoded.rdd.flatMap(x=> encodeSeq(x.getSeq[String](0)))
encoded: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[336] at flatMap at <console>:44
是unencoded
检查编码结果会给出:
org.apache.spark.sql.DataFrame = [col1: array<string>, col2: array<string> ... 3 more fields]
我还是Spark和Scala的新手。我在地图上或某处做错了吗?还是有更好的方法来实现这一目标?