levenshtein-distance
может быть подходящей мерой для сходства:
val df : DataFrame = Seq(
("f1",Seq(1,0,0,0,1,0)),
("f2",Seq(0,0,1,0,1,1)),
("f3",Seq(1,1,1,0,0,0)),
("f4",Seq(1,1,0,0,1,0)) // very similar to f1
).toDF("function_name","result_list")
df.alias("a").join(
df.alias("b"),
$"a.function_name" =!= $"b.function_name"
)
.withColumn("distance",levenshtein($"a.result_list".cast("string"),$"b.result_list".cast("string")))
.where($"distance"<=1) // similarity threshold
// avoid duplication
.select(sort_array(array($"a.function_name",$"b.function_name")).as("pairing"),$"distance")
.dropDuplicates("pairing")
.show()
дает:
+--------+--------+
| pairing|distance|
+--------+--------+
|[f1, f4]| 1|
+--------+--------+
Вы также можете использовать levenshtein
в условии соединения, но тогда вы потеряете информация о расстоянии:
df.alias("a").join(
df.alias("b"),
$"a.function_name" =!= $"b.function_name" and levenshtein($"a.result_list".cast("string"),$"b.result_list".cast("string")) <= 1)