在PySpark上的RDD中的字典之间减去值

时间:2018-04-08 09:13:58

标签: python dictionary apache-spark pyspark rdd

我创建了RDD,其中每个元素都是字典。

rdd.take(2)

[{'actor': 'brad',
  'good': 1,
  'bad': 0,
  'average': 0,}
 {'actor': 'tom',
  'good': 0,
  'bad': 1,
  'average': 1,}]

我正在尝试对数据执行算术运算,即 'actor':'brad'和'actor':'tom',我想减去具有相同键的其他值,然后找到最后的总和

那是:

(1-0)+(0-1)+(0-1)= -1

由于这是RDD形式,我试图做的是:

d1=rdd.filter(lambda x: x['name']=='brad').first()

 {'actor': 'brad',
  'good': 1,
  'bad': 0,
  'average': 0,}

 d2=rdd.filter(lambda x: x['name']=='tom').first()

 {'actor': 'tom',
  'good': 0,
  'bad': 1,
  'average': 1,}

这给了我带有'brad'和'tom'值的字典。如何进行算术运算?

我试过这样做:

d3 = {key: d1] - d2.get(key, 0) for key in d1.keys()}

但这给了我错误。

有没有更好的方法来操作RDD本身的字典而不是将其分解为基本字典?

谢谢

1 个答案:

答案 0 :(得分:1)

您的一些错误是由于使用了错误的密钥("name"不在字典中)。但除此之外,收集普通词典可能是最合适的方法(见底部注释)。

d1=rdd.filter(lambda x: x['actor']=='brad').first()
d2=rdd.filter(lambda x: x['actor']=='tom').first()

使用预定义键列表:

keys = ['good', 'bad', 'average']

您可以使用理解来制作结果词典:

{key: d1[key] - d2[key] for key in keys}
# outputs:
{'average': -1, 'bad': -1, 'good': 1}

然后可以简单地计算所有词典值的总和:

print(sum([v for v in dc.values()])) #-1

如果它们被收集在并行列表中,您甚至可以在多个词典上执行此操作(假设您确切知道在订单中收集了2个RDD,从而允许通过索引操作进行索引)

[{key: d1[key] - d2[key] for key in keys}\
  for d1,d2 in zip(dicRdd1.collect(), dicRdd2.collect())]

您可以使用(您的示例词典)测试此逻辑:

[{key: d1[key] - d2[key] for key in keys}\
  for d1,d2 in zip([d1], [d2])]

注意:您应该避免在Spark的分布式reduce操作中执行减法操作。这只是因为减法不是可交换的,并且会导致不可预测的结果。