Список как ключ для PySpark's ReduceByKey

Я пытаюсь вызвать функцию pyspark reduByKey для данных формата (([a,b,c], 1), ([a,b,c], 1), ([a,d,b,e], 1), ...

Кажется, что pyspark не примет массив в качестве ключа в обычном ключе, уменьшение значения простым применением.reduceByKey(add).

Я уже пытался сначала преобразовать массив в строку, .map((x,y): (str(x),y)) но это не работает, потому что постобработка строк обратно в массивы слишком медленная.

Есть ли способ заставить pyspark использовать массив в качестве ключа или использовать другую функцию для быстрого преобразования строк обратно в массивы?

вот соответствующий код ошибки

  File "/home/jan/Documents/spark-1.4.0/python/lib/pyspark.zip/pyspark/shuffle.py", line 268, in mergeValues
    d[k] = comb(d[k], v) if k in d else creator(v)
TypeError: unhashable type: 'list'
    enter code here

РЕЗЮМЕ:

вход:x =[([a,b,c], 1), ([a,b,c], 1), ([a,d,b,e], 1), ...]

желаемый результат:y =[([a,b,c], 2), ([a,d,b,e], 1),...]так что я мог получить доступ a от y[0][0][0] а также 2 от y[0][1]

1 ответ

Решение

Попробуй это:

rdd.map(lambda (k, v): (tuple(k), v)).groupByKey()

Поскольку списки Python являются изменяемыми, это означает, что их нельзя хэшировать (не предоставляйте __hash__ метод):

>>> a_list = [1, 2, 3]
>>> a_list.__hash__ is None
True
>>> hash(a_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Кортежи с другой стороны являются неизменными и обеспечивают __hash__ Реализация метода:

>>> a_tuple = (1, 2, 3)
>>> a_tuple.__hash__ is None
False
>>> hash(a_tuple)
2528502973977326415

следовательно, может быть использован в качестве ключа. Точно так же, если вы хотите использовать уникальные значения в качестве ключа, вы должны использовать frozenset:

rdd.map(lambda (k, v): (frozenset(k), v)).groupByKey().collect()

вместо set,

# This will fail with TypeError: unhashable type: 'set'
rdd.map(lambda (k, v): (set(k), v)).groupByKey().collect()
Другие вопросы по тегам