检查元素是否在rdd的文档中

时间:2015-06-29 17:23:39

标签: mapreduce apache-spark pyspark

我在pySpark中有这样的rdd1 :(请原谅任何轻微的语法错误):

[(id1,(1,2,3)), (id2,(3,4,5))]

我有另一个rdd2持有这样的:(2,3,4)。

现在我想看看rdd2的每个元素在它出现多少个rdd1子列表中,例如:预期产出rdd(或收集清单我不在乎)

(2, [id1]),(3,[id1,id2]),(4,[id2])

这是我到目前为止(注意rdd2必须是行/算法中的第一项)

rdd2.map(lambda x: (x, x in rdd.map(lambda y:y[1])))

即使这样,我只能给出真/假作为对元组的第二项,我可以忍受它,但即使这样也行不通。尝试在rdd1地图的匿名函数内的rdd2上执行映射时失败。

知道如何让这个朝着正确的方向前进吗?

1 个答案:

答案 0 :(得分:1)

如果rrd2相对较小(适合记忆):

pairs1 = rdd1.flatMap(lambda (k, vals): ((v, k) for v in vals))
vals_set = sc.broadcast(set(rdd2.collect()))
(pairs1
    .filter(lambda (k, v): k in vals_set.value)
    .groupByKey())

如果没有,您可以从前一部分中取pairs1并使用join:

pairs2 = rdd2.map(lambda x: (x, None))
(pairs2
    .leftOuterJoin(pairs1)
    .map(lambda (k, (_, v)): (k, v))
    .groupByKey())

与往常一样,如果这只是一个中间结构,您应该考虑reduceByKeyaggregateByKeycombineByKey而不是groupByKey。如果是最终结构,您可以添加.mapValues(list)

最后,您可以尝试使用Spark数据框:

df1 = sqlContext.createDataFrame(
    rdd1.flatMap(lambda (v, keys): ({'k': k, 'v': v} for k in keys)))
df2 = sqlContext.createDataFrame(rdd2.map(lambda k: {'k': k}))

(df1
    .join(df2, df1.k ==  df2.k, 'leftsemi')
    .map(lambda r: (r.k, r.v)).groupByKey())