pyspark / python 3.6 (TypeError: объект 'int' не может быть подписан) список / кортежи - PullRequest
0 голосов
/ 05 мая 2018

У меня есть этот код в pyspark / python:

n -> число чисел нового списка

n = 2

new tuple ( x, y, z )

Где:

x --> index

y --> list [where variable n is a number of itens of list]

z --> value of front value of list

Я делаю этот код:

RDD_Dados = RDD_one.map(lambda x: (x[0], 
                                  [list(x[i][1]) for i in range(n)],
                                  x[i+1][1])
                        )

Содержимое RDD_one:

(0, [(0, '5'), (1, '1'), (2, '2'), (3, '4'), (4, '4'), (5, '3.5'), (6, '-2'), (7, '1'), (8, '2'), (9, '0')])
(1, [(1, '1'), (2, '2'), (3, '4'), (4, '4'), (5, '3.5'), (6, '-2'), (7, '1'), (8, '2'), (9, '0')])
(2, [(2, '2'), (3, '4'), (4, '4'), (5, '3.5'), (6, '-2'), (7, '1'), (8, '2'), (9, '0')])
(3, [(3, '4'), (4, '4'), (5, '3.5'), (6, '-2'), (7, '1'), (8, '2'), (9, '0')])
(4, [(4, '4'), (5, '3.5'), (6, '-2'), (7, '1'), (8, '2'), (9, '0')])
(5, [(5, '3.5'), (6, '-2'), (7, '1'), (8, '2'), (9, '0')])
(6, [(6, '-2'), (7, '1'), (8, '2'), (9, '0')])
(7, [(7, '1'), (8, '2'), (9, '0')])
(8, [(8, '2'), (9, '0')])
(9, [(9, '0')])

Я хотел бы получить каждый второстепенный предмет каждого дупла и создать новый список, подобный этому:

(0, ['5','1'], '2')
(1, ['1','2'], '4')
(2, ['2','4'], '4')
(3, ['4','4'], '3.5')
(4, ['4','3.5'], '-2')
(5, ['3.5','-2'], '1')
(6, ['-2','1'], '2')
(7, ['1','2'], '0')

но не работает.

Я получаю эту ошибку:

---------------------------------------------------------------------------
Py4JJavaError                             Traceback (most recent call last)
<ipython-input-12-3532f6a9c36a> in <module>(
59 RDD_Dados = RDD_one.map(lambda x: (x[0],[list(x[i][1]) for i in range(n)],x[i+1][1]))

  File "C:\Spark\spark-2.3.0-bin-hadoop2.7\python\lib\pyspark.zip\pyspark\worker.py", line 229, in main
File "C:\Spark\spark-2.3.0-bin-hadoop2.7\python\lib\pyspark.zip\pyspark\worker.py", line 224, in process
File "C:\Spark\spark-2.3.0-bin-hadoop2.7\python\lib\pyspark.zip\pyspark\serializers.py", line 372, in dump_stream
vs = list(itertools.islice(iterator, batch))
File "<ipython-input-12-3532f6a9c36a>", line 59, in <lambda>
File "<ipython-input-12-3532f6a9c36a>", line 59, in <listcomp>
TypeError: 'int' object is not subscriptable

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Я решаю эту проблему, делая это:

Сначала я делаю СДР, используя фильтр для удаления ненужных данных, в соответствии с номером параметра N.

RDDFilter = DadosAgrupadosPorChaveOrdenados.filter(lambda x: n < len(x[1]))

После этого я делаю другие данные для монтажа RDD, как мне было нужно:

DadosFinal = RDDFilter.map(lambda x: (x[0], 
                              [x[1][i][1] for i in range(0,int(n))], 
                              x[1][int(n)][1]))

Большое спасибо за любую помощь.

0 голосов
/ 05 мая 2018

Изменение

RDD_Dados = RDD_one.map(lambda x: (x[0], 
                                  [list(x[i][1]) for i in range(n)],
                                  x[i+1][1]))

для

RDD_Dados = RDD_one.map(lambda x: (x[0], 
                                  [x[i][1] for i in range(1,n+1)],
                                  x[n][1]))

range начинается с 0, поэтому вы делаете x[0][1] на первой итерации. Однако x[0] является целым числом, поэтому ваша проблема. Кроме того, вам не нужно переносить x[i][1] с list, иначе вы получите, например, (0, [ ['5'], ['1'] ], '2') вместо (0, ['5','1'], '2')


Edit:

Для более обобщенного и гибкого подхода вы можете создать пользовательскую функцию, в которой вы сможете дополнительно расширять логику.
Например:

def my_logic(x):
   ret = [x[0], []]
   for i in range(1, n):
       try:
           ret[1].append(x[1][i][1])
       except IndexError:
           ret[1].append(0)
           break
   if len(x[1]) > n:
       ret.append(x[1][n][1])
   else:
       ret.append(0)
   return ret

А потом просто сделай

RDD_Dados = RDD_one.map(my_logic)
...