Подготовьте мои bigdata с помощью Spark через Python

Мой размер в 100 м, квантованные данные:

(1424411938', [3885, 7898])
(3333333333', [3885, 7898])

Желаемый результат:

(3885, [3333333333, 1424411938])
(7898, [3333333333, 1424411938])

Так что я хочу, это преобразовать данные, чтобы я группировал 3885 (например) со всеми data[0], которые его имеют). Вот что я сделал в :

def prepare(data):
    result = []
    for point_id, cluster in data:
        for index, c in enumerate(cluster):
            found = 0
            for res in result:
                if c == res[0]:
                    found = 1
            if(found == 0):
                result.append((c, []))
            for res in result:
                if c == res[0]:
                    res[1].append(point_id)
    return result

но когда я mapPartitions() 'ed data RDD с prepare(), он, похоже, делает то, что я хочу только в текущем разделе, поэтому возвращаю больший результат, чем желаемый.

Например, если первая запись в начале была в первом разделе, а вторая - во втором, я бы получил результат:

(3885, [3333333333])
(7898, [3333333333])
(3885, [1424411938])
(7898, [1424411938])

Как изменить мой prepare(), чтобы получить желаемый эффект? В качестве альтернативы, как обрабатывать результат, создаваемый prepare(), чтобы я мог получить желаемый результат?


Как вы уже заметили из кода, мне вообще не нужна скорость.

Вот способ создания данных:

data = []
from random import randint
for i in xrange(0, 10):
    data.append((randint(0, 100000000), (randint(0, 16000), randint(0, 16000))))
data = sc.parallelize(data)

Ответ 1

Для достижения этой цели вы можете использовать кучу базовых преобразований pyspark.

>>> rdd = sc.parallelize([(1424411938, [3885, 7898]),(3333333333, [3885, 7898])])
>>> r = rdd.flatMap(lambda x: ((a,x[0]) for a in x[1]))

Мы использовали flatMap, чтобы иметь пару ключей, значений для каждого элемента в x[1], и мы изменили формат строки данных на (a, x[0]), a здесь каждый элемент в x[1]. Чтобы лучше понять flatMap, вы можете посмотреть документацию.

>>> r2 = r.groupByKey().map(lambda x: (x[0],tuple(x[1])))

Мы просто сгруппировали все пары ключей, значений по их ключам и использовали функцию tuple для преобразования итерации в кортеж.

>>> r2.collect()
[(3885, (1424411938, 3333333333)), (7898, (1424411938, 3333333333))]

Как вы сказали, вы можете использовать [: 150], чтобы иметь первые 150 элементов, я думаю, это было бы правильное использование:

r2 = r.groupByKey().map(lambda x: (x[0],tuple(x[1])[:150]))

Я старался быть настолько объяснительным, насколько это возможно. Надеюсь, это поможет.