data :DataFrame
具有15个字符串列。
目标:创建一个包含所有15列中不同字符串的列表。
示例:如果"吉他"一词在第一列中出现一次或多次,以及在第四列中,它必须出现在最终列表中。
建议的解决方案,但不是理想的:udf是在一个新列中限制所有列的选项,然后我可以使用将提取词汇的CountVectorizer
处理该列。但是UDF受到限制,因为它们接受最大10个输入参数(即我不能将10列超过10列传递给UDF),因此该解决方案必须实现两个UDF,这是第一个连接10列的UDF,第二列是连接的。接下来5列的第一个UDF的输出。
我正在为此问题寻找一个更有效的紧凑解决方案,更通常是解决UDF的输入参数有限的解决方案的解决方案。
SPARK-SQL函数array
可以将任何数量的结肠(同一类型的)映射到该类型的数组列。
从那里开始,您可以在数组类型上创建一个UDF,也可以按建议使用CountDectorizer。
scala> val data = spark.sparkContext.parallelize(Seq(("a1", "b1", "c1"), ("a2", "b2", "c2"))).toDF("a", "b", "c")
data: org.apache.spark.sql.DataFrame = [a: string, b: string ... 1 more field]
scala> data.show
+---+---+---+
| a| b| c|
+---+---+---+
| a1| b1| c1|
| a2| b2| c2|
+---+---+---+
scala> data.select(array("a", "b", "c")).show
+--------------+
|array(a, b, c)|
+--------------+
| [a1, b1, c1]|
| [a2, b2, c2]|
+--------------+
但是,比计数向量器要简单:
scala> data.select(explode(array("a", "b", "c"))).distinct.show
+---+
|col|
+---+
| b2|
| c1|
| a2|
| b1|
| a1|
| c2|
+---+
如果直接进行RDD对您来说还不错,那么仍然会更简单(并且可能更快):
scala> data.rdd.flatMap(r=>r.toSeq).distinct.collect
res4: Array[Any] = Array(b2, a1, a2, c1, c2, b1)