2016-10-06 5 views
0

У меня есть набор данных, который выглядит, как это в pyspark:pyspark redueByKey изменить одиночные результаты

samp = sc.parallelize([(1,'TAGA'), (1, 'TGGA'), (1, 'ATGA'), (1, 'GTGT'), (2, 'GTAT'), (2, 'ATGT'), (3, 'TAAT'), (4, 'TAGC')]) 

У меня есть функция, я использую, чтобы объединить строки:

def combine_strings(x,y): 
     if (isinstance(x,list) and isinstance(y, list)): 
      z = x + y 
      return z 
     if (isinstance(x, list) and isinstance(y, str)): 
      x.append(y) 
      return x 
     if (isinstance(x, str) and isinstance(y, list)): 
      y.append(x) 
      return y 
     return [x,y] 

В результате я получаете:

samp.reduceByKey(lambda x,y : combine_strings(x,y)).collect() 
[(1, ['TAGA', 'TGGA', 'ATGA', 'GTGT']), (2, ['GTAT', 'ATGT']), (3, 'TAAT'), (4, 'TAGC')] 

Что я хочу:

[(1, ['TAGA', 'TGGA', 'ATGA', 'GTGT']), (2, ['GTAT', 'ATGT']), (3, ['TAAT']), (4, ['TAGC'])]

Где все - массив. Я не могу сказать, вызывает ли pyspark comb_strings результат, когда есть 1 запись или я могу сказать, что reduceByKey что-то делает с результатами singleton? Как изменить функцию reduceByKey() или comb_strings, чтобы создать то, что мне хотелось бы?

ответ

0

Вы можете сначала отобразить значения в списках, а затем только объединить эти списки:

samp.mapValues(lambda x : [x]).reduceByKey(lambda x,y : x + y).collect() 

Проблема здесь состоит в том, что эти одиночек не влияет на reduceByKey. Вот еще один пример:

samp = sc.parallelize([(1,1),(2,2),(2,2),(3,3)]) 
>>> samp.reduceByKey(lambda x, y : x + y + 1).collect() 
[(3, 3), (1, 1), (2, 5)] 
+0

Это работает для решения этой проблемы. Благодаря! Вы знаете, есть ли способ сделать другую часть ответа? (т. е. делать что-то конкретное для синглетов в reduceByKey) –

+1

Нельзя достичь такого же результата с помощью reduceByKey, поскольку метод не будет вызываться, когда есть только уникальный ключ. – NiVeR

Смежные вопросы