我有一个包含2个字段/列的数据集javah
和col1
,两者都是col2
类型。我正在为Array[String]
的每个元素按排序顺序从col1
收集不同的元素,并仅保留名为_dArr
的List中的第一个元素。问题是_list
,这需要花费很多时间。有没有更好的方法可以用来提高代码的效率。我还使用了一个空数据集,并使用union来添加新行,我从每个for循环获得val arr = _ds.take(1)(0)
,以便稍后我可以对该结果数据集执行_ds
以获得collect
结果1}}。但它也花了很多时间。
List[Array[String]]
示例输入:
case class ColFields(fields: Array[String])
var _dArr = null: Array[String]
var _list = List[ClassFields]()
_dArr.foreach(x => {
val _ds = df.select("col1")
.where(array_contains(df("col2"), x))
.withColumn("col1", explode(col("col1")))
.agg(sort_array(collect_set("col1")).alias("col1")).as[Array[String]]
.cache()
val arr = _ds.take(1)(0)
// val arr = _ds.collect()(0) // Does not make any performance difference.
distPredDS.unpersist()
_list ::= ColFields(arr)
})
输出:
_dArr = Array[x, y, w]
col1 col2
------------------
[a, b] [w, x]
[a, d] [x, y]
[c, d, f] [y]
[h] [w]
,或者
List[Array[a, b, d], Array[a, c, d, f], Array[a, b, h]]
答案 0 :(得分:0)
根据我的理解,你试图找出col2是否包含dArray中的任何元素,如果是,则获取从col1排序到列表中的第一个元素。
val dArr = Array("x","y","z")
val df = Seq((Array("s","x","w"),Array("a","x")),(Array("v","d","e"),Array("b","z")),(Array("a","b","c"),Array("f","d"))).toDF("col1","col2")
def checkValues(arr: Array[String]) = udf((col1: Seq[String], col2: Seq[String]) => { if (col2.exists(arr.contains)) col1.toList.sortWith(_ < _).head else ""})
df.withColumn("col1_first", checkValues(dArr)($"col1",$"col2")).select($"col1_first").collectAsList
我在这里通过col1&amp; col2到UDF,它将col2与arr进行比较,并在对col1进行排序后得到col1的第一个元素。然后,您可以过滤非空值和collectAsList。
请告诉我它是否有效,否则请提供更多信息,包括您期望的数据样本。
我已修改,但爆炸似乎是一项代价高昂的操作。看看它是否有助于您的数据集,
val dArr = Array("x","y","w")
val df = Seq((Array("a","b"),Array("w","x")),(Array("a","d"),Array("x","y")),(Array("c","d","f"),Array("x","y")),(Array("h"),Array("w"))).toDF("col1","col2")
def checkValues(arr: Array[String]) = udf((col1: Seq[String], col2: Seq[String]) => { arr.foldLeft(Array[String]()){case(acc, elem) => {if (col2.contains(elem)) acc :+ elem else acc}}})
val df_1 = df.withColumn("arrValues", explode(checkValues(dArr)($"col1",$"col2")))
df_1.select($"arrValues",explode($"col1").as("col1")).groupBy($"arrValues").agg(collect_set($"col1").as("col1_list")).show