我是新手,试图找到一种方法将信息从一个rdd集成到另一个rdd,但是它们的结构不适合标准的连接函数
我有这种格式的rdd:
[{a:a1, b:b1, c:[1,2,3,4], d:d1},
{a:a2, b:b2, c:[5,6,7,8], d:d2}]
以及另一种格式:
[{1:x1},{2,x2},{3,x3},{4,x4},{5,x5},{6,x6},{7,x7},{8,x8}]
我想将第二个rdd中的值与第一个rdd中的键匹配(它们位于c键的列表值中)。我知道如果他们在那里操纵它们,所以我不太关心最终输出,但我可能希望看到这样的东西:
[{a:a1, b:b1, c:[1,2,3,4],c0: [x1,x2,x3,x4], d:d1},
{a:a2, b:b2, c:[5,6,7,8],c0: [x5,x6,x7,x8], d:d2}]
或者这个:
[{a:a1, b:b1, c:[(1,x1),(2,x2),(3,x3),(4,x4)], d:d1},
{a:a2, b:b2, c:[(5,x5),(6,x6),(7,x7),(8,x8)], d:d2}]
或其他任何可以匹配第二个rdd中的键与第一个中的值的内容。我考虑将第二个rdd变成一个字典,我知道如何使用它,但我认为我的数据太大了。
非常感谢你,我真的很感激。
答案 0 :(得分:1)
join
之后 flatMap
,或cartesian
进行了太多的随机播放。
其中一种可能的解决方案是在cartesian
之后groupBy
使用HashPartitioner
。
(抱歉,这是scala
代码)
val rdd0: RDD[(String, String, Seq[Int], String)]
val rdd1: RDD[(Int, String)]
val partitioner = new HashPartitioner(rdd0.partitions.size)
// here is the point!
val grouped = rdd1.groupBy(partitioner.getPartition(_))
val result = rdd0.cartesian(grouped).map { case (left, (_, right)) =>
val map = right.toMap
(left._1, left._2, left._4) -> left._3.flatMap(v => map.get(v).map(v -> _))
}.groupByKey().map { case (key, value) =>
(key._1, key._2, value.flatten.toSeq, key._3)
}
答案 1 :(得分:1)
我将假设rdd1
是包含{a:a1, b:b1, c:[1,2,3,4], d:d1}
的输入,而rdd2
包含元组[(1, x1), (2, x2), (3, x3), (4, x4), (5, x5), (6, x6), (7, x7), (8, x8)]
。我还将假设" c"中的所有值。 rdd1
中的字段可以在rdd2
中找到。如果没有,您需要更改下面的一些代码。
我有时必须解决这类问题。如果rdd2
足够小,我通常会进行地图侧连接,首先广播对象,然后进行简单的查找。
def augment_rdd1(line, lookup):
c0 = []
for key in line['c']:
c0.append(lookup.value[key])
return c0
lookup = sc.broadcast(dict(rdd2.collect()))
output = rdd1.map(lambda line: (line, augment_rdd1(line, lookup)))
如果rdd2
太大而无法广播,我通常会使用flatMap
将rdd1
的每一行映射到与&中的元素一样多的行34; C"场,例如{a:a1, b:b1, c:[1,2,3,4], d:d1}
将映射到
(1, {a:a1, b:b1, c:[1,2,3,4], d:d1})
(2, {a:a1, b:b1, c:[1,2,3,4], d:d1})
(3, {a:a1, b:b1, c:[1,2,3,4], d:d1})
(4, {a:a1, b:b1, c:[1,2,3,4], d:d1})
flatMap是
flat_rdd1 = rdd1.flatMap(lambda line: [(key, line) for key in line['c'])])
然后,我将与rdd2一起获得一个RDD,其中包含:
({a:a1, b:b1, c:[1,2,3,4], d:d1}, x1)
({a:a1, b:b1, c:[1,2,3,4], d:d1}, x2)
({a:a1, b:b1, c:[1,2,3,4], d:d1}, x3)
({a:a1, b:b1, c:[1,2,3,4], d:d1}, x4)
联接如下:
rdd2_tuple = rdd2.map(lambda line: line.items())
joined_rdd = flat_rdd1.join(rdd2_tuple).map(lambda x: x[1])
最后,您需要做的只是groupByKey
获取({a:a1, b:b1, c:[1,2,3,4], d:d1}, [x1, x2, x3, x4])
:
result = joined_rdd.groupByKey()