Мне нужно сравнить разные строки набора данных два к двум. В идеале я бы сделал самодекартово произведение набора данных, затем удалил бы повторяющиеся сравнения (поскольку A, B
совпадает с B, A
) и, наконец, я бы сделал map
, чтобы решить, равны ли каждая пара строк или нет. Однако это приведет к огромному количеству строк, и я не могу позволить себе вычислительные затраты, которые это повлечет.
Чтобы максимально сократить результирующее количество строк, я хотел бы отсортировать строки и применить самодекартово произведение только к разным подмножествам всего набора данных. Например, подмножества будут следующими:
- От строки 0 до 100
- С 50 по 150 ряд
- С 100 по 200 ряд
- ....
Таким образом, я бы сравнил каждую строку с ее соседями, и конечное количество сравниваемых строк было бы намного меньше, чем если бы я выполнял самодекартово произведение по всему набору данных.
Моя попытка
На самом деле я реализовал решение, но по какой-то причине это занимает много времени, даже если набор данных небольшой.
Во-первых, я сортирую и архивирую набор данных, чтобы идентифицировать каждый столбец.
val sortedByTitle = journalArticles.orderBy("title")
val withIndex = sortedByTitle.rdd.zipWithIndex().toDF("article", "index").as[IndexArticle]
Затем я сделал функцию для деления и самодекартова произведения:
def divideAndCartesian(data: Dataset[IndexArticle], fromIndex: Long, divisionSize: Int): Dataset[CartessianIndexArticles] = {
val division = data.filter(x => x.index >= fromIndex && x.index < fromIndex + divisionSize)
if(division.count() == 0) Seq.empty[(JournalArticle, Long, JournalArticle, Long)].toDF("article1", "index1", "article2", "index2").as[CartessianIndexArticles]
else
division.crossJoin(division).toDF("article1", "index1", "article2", "index2").as[CartessianIndexArticles].union(divideAndCartesian(data, fromIndex + (divisionSize / 2), divisionSize))
}
Любые идеи?
Благодарю вас!