У меня есть RDD пар (ключ, значение) формы
RDD[(
scala.collection.immutable.Vector[(Byte, Byte)],
scala.collection.immutable.Vector[Int]
)]
где key
- Vector[(Byte, Byte)]
, а value
- Vector[Int]
.
Например, содержимое RDD может быть таким, как показано ниже.
(Vector((3,3), (5,5)), Vector(1, 2)),
(Vector((1,1), (2,2), (3,3),(4,4), (5,5)), Vector(1, 3, 4, 2)),
(Vector((1,1), (2,3)), Vector(1, 4, 2)),
(Vector((1,1), (2,2), (5,5)), Vector(3, 5)),
Я хотел бы сделать манипуляцию на этом RDD, чтобы в результирующем RDD для каждой пары (ключ, значение) выполнялось следующее условие.
Когда ключ "k1" этого RDD является подмножеством ключа "k2" этого RDD, значения k1 должны обновляться, чтобы также содержать значения k2, в то время как значения k2 останутся неизменными.
В приведенном выше примере RDD станет,
(Vector((3,3), (5,5)), Vector(1, 2, 3, 4)),
(Vector((1,1), (2,2), (3,3), (4,4), (5,5)), Vector(1, 3, 4, 2))
(Vector((1,1), (2,3)), Vector(1, 4, 2))
(Vector((1,1), (2,2), (5,5)), Vector(1, 2, 3, 4, 5))
Я задал аналогичный вопрос здесь. Предоставленное решение приведено ниже (слегка изменено в соответствии с моей проблемой). Это работает, но очень неэффективно для больших наборов данных.
val resultPre = rddIn
.flatMap { case (colMapkeys, rowIds) =>
colMapkeys.subsets.tail.map(_ -> rowIds)
}
.reduceByKey(_ ++ _)
.join(rddIn map identity[(Seq[(Byte, Byte)], Vector[Int])])
.map{ case (key, (v, _)) => (key, v) }
implicit class SubSetsOps[T](val elems: Seq[T]) extends AnyVal {
def subsets: Vector[Seq[T]] = elems match {
case Seq() => Vector(elems)
case elem +: rest => {
val recur = rest.subsets
recur ++ recur.map(elem +: _)
}
}
}
Генерация всех подмножеств ключей, а затем их фильтрация путем соединения с оригинальными ключами RDD представляется неэффективной.
Как я могу справиться с этим эффективно?