Вычитание значений между словарями в RDD на PySpark

avatar
Jerry George
8 апреля 2018 в 09:13
522
1
2

Я создал RDD, где каждый элемент является словарем.

rdd.take(2)

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

Я пытаюсь выполнить арифметические операции над данными, т.е. «актер»: «брэд» и «актер»: «том», я хочу вычесть другие значения, имеющие тот же ключ, а затем найти окончательную сумму

То есть:

(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, а не разбивая его на базовый словарь?

Спасибо

Источник
Ramkishore M
8 апреля 2018 в 09:44
0

sum((d1[k] - d2[k]) for k in d1.keys() if k in ['good','bad','average'])

Ответы (1)

avatar
ernest_k
8 апреля 2018 в 10:10
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 СДР собраны в порядке, допускающем операцию индекс за индексом)

[{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. Это просто потому, что вычитание не является коммутативным, и это может привести к непредсказуемым результатам.