Кажется, что вы хотите сгенерировать все перестановки элементов в rdd
, где каждая строка содержит уникальные значения.
Один из способов - сначала создать вспомогательную функцию для генерации желаемой комбинации длиныn
:
from functools import reduce
from itertools import chain
def combinations_of_length_n(rdd, n):
# for n > 0
return reduce(
lambda a, b: a.cartesian(b).map(lambda x: tuple(chain.from_iterable(x))),
[rdd]*n
).filter(lambda x: len(set(x))==n)
По сути, функция будет делать n
декартовы произведения вашего rdd
с собой и сохранять только те строки, в которых все значения различны.
Мыможете проверить это для n = [2, 3]
:
print(combinations_of_length_n(rdd1, n=2).collect())
#[('P', 'T'), ('P', 'K'), ('T', 'P'), ('K', 'P'), ('T', 'K'), ('K', 'T')]
print(combinations_of_length_n(rdd1, n=3).collect())
#[('P', 'T', 'K'),
# ('P', 'K', 'T'),
# ('T', 'P', 'K'),
# ('K', 'P', 'T'),
# ('T', 'K', 'P'),
# ('K', 'T', 'P')]
Конечный результат, который вам нужен, это просто union
из этих промежуточных результатов с исходным rdd
(со значениями, сопоставленными с tuple
s),
rdd1.map(lambda x: tuple((x,)))\
.union(combinations_of_length_n(rdd1, 2))\
.union(combinations_of_length_n(rdd1, 3)).collect()
#[('P',),
# ('T',),
# ('K',),
# ('P', 'T'),
# ('P', 'K'),
# ('T', 'P'),
# ('K', 'P'),
# ('T', 'K'),
# ('K', 'T'),
# ('P', 'T', 'K'),
# ('P', 'K', 'T'),
# ('T', 'P', 'K'),
# ('K', 'P', 'T'),
# ('T', 'K', 'P'),
# ('K', 'T', 'P')]
Обобщение для любого максимального числа повторений:
num_reps = 3
reduce(
lambda a, b: a.union(b),
[
combinations_of_length_n(rdd1.map(lambda x: tuple((x,))), i+1)
for i in range(num_reps)
]
).collect()
#Same as above
Примечание : декартовы произведения являются дорогостоящими операциями, и их следует избегатькогда это возможно.