Spark - 在特定字段上加入json RDD(无键值)

时间:2015-08-24 21:30:50

标签: join apache-spark

我有两个Spark 1.4.1 PipelineRDD(我不确定那是什么类型的对象:-s:

1)id列表(ids_alsaciens RDD)

2)人员名单(personnes RDD)

' Personnes' RDD有4个字段,采用json格式,密钥为" id"。 我可能在此表中为同一个人提供了几行(id是相同的)

我想获取“人物”中的所有内容。 RDD的ID包含在' alsacien'表

我怎么能在火花中做到这一点?

>type(ids_alsaciens)
pyspark.rdd.PipelinedRDD
>type(personnes)
pyspark.rdd.PipelinedRDD

>ids_alsaciens.take(10)
    [u'1933992',
     u'2705919',
     u'2914684',
     u'2915444',
     u'11602833',
     u'11801394',
     u'10707371',
     u'2018422',
     u'2312432',
     u'233375']
    >personnes.take(3)
    [{'date': '2013-06-03 00:00',
      'field': 'WAID_INDIVIDU_WC_NUMNNI',
      'id': '10000149',
      'value': '2770278'},
     {'date': '2013-05-15 00:00',
      'field': 'WAID_INDIVIDU_WC_NUMNNI',
      'id': '10009910',
      'value': '2570631'},
     {'date': '2013-03-01 00:00',
      'field': 'WAID_INDIVIDU_WC_NUMNNI',
      'id': '10014405',
      'value': '1840288'}]

修改

试过: personnes.filter(lambda x:x in ids_alsaciens)

得到例外: 例外:您似乎正在尝试广播RDD或从动作或转换中引用RDD。 RDD转换和操作只能由驱动程序调用,而不能在其他转换内部调用;例如,rdd1.map(lambda x:rdd2.values.count()* x)无效,因为无法在rdd1.map转换内执行值转换和计数操作。有关更多信息,请参阅SPARK-5063。

1 个答案:

答案 0 :(得分:1)

发生错误SPARK-5063是因为不允许在地图内调用RDD函数,因为运行map任务的spark worker无法自行完成工作。

使用Spark RDD.join:

来自documentation

 let history: AnyObject? = poolHistory.valueForKey("serviceHistory")
 print("\(history)")
     

join(otherDataset, [numTasks]) (K, V)类型的数据集上调用时,返回(K, W)对的数据集,其中包含每个键的所有元素对

秘诀是要知道Spark将所有2元组视为(K, (V, W))对,您可以使用(key,value)制作自己的对:

RDD.map()

kv_ids_alsaciens = ids_alsaciens.map(lambda id: (id, 0)) (k,v)的ids_alsaciens中生成k=id个对。这有点浪费,但我没有测试你是否可以消除v=0

然后与personnes:

v

现在我们可以使用join

kv_personnes = personnes.map(lambda p: (p['id'],p))

虽然将是RDD,其条目如

joined_kv_ids_alsaciens_personnes = kv_ids_alsaciens.join(kv_personnes)

其中第一项是匹配的ID,和 第二项是一对(10000149, (0, {'date': '2013-06-03 00:00', 'field': 'WAID_INDIVIDU_WC_NUMNNI', 'id': '10000149', 'value': '2770278'})) (match1,match2)总是match1因为我们的第一个数据集总是如此 该对中的值为00为dict 人格数据。

这不是我们所需要的。更好的格式可能是只发出字典。我们可以用另一张地图做到这一点。

match2

一起使用cache()来获取内存中的最终结果:

match_personnes = joined_kv_ids_alsaciens_personnes.map(lambda (k,(v1,v2)): v2)

测试:

match_personnes = (ids_alsaciens
                   .map(lambda id: (id, 0))
                   .join(personnes.map(lambda p: (p['id'],p)))
                   .map(lambda (k,(v1,v2)): v2)
                   .cache()
                   )