Что не так с этим Spark RDD, отображенным с помощью лямбда-функции с двумя аргументами? - PullRequest
0 голосов
/ 27 декабря 2018

Цель #

  • Распечатать набор данных с названием фильма и числом раз, когда он был оценен.
  • Это простой способ получить самый «популярный» фильм

Данные

  • Один файл с именем "u.data" с movieID, userID, рейтингами, отметкой времени
  • Один файл с именем "u.элемент "с идентификатором фильма, названием фильма и информацией о каждом фильме

Метод

  • Создание ключа словаря = MovieID, значения = Имя из u.itemfiles
  • Передача словаря узлам-исполнителям в кластере
  • Создание rdd с MovieID и 1 в каждой строке
  • Reduceэтот rdd по movieID и суммируйте каждое из них
  • Отразите ключ (movieID) и значение (Total), чтобы отсортировать набор данных по этому общему количеству

Issue

  • Затем мне нужно сопоставить movieID с транслируемым словарем, но я получаю синтаксическую ошибку в этой строке:
    sortedMoviesWithNames = sortedMovies.map(lambda (count, movie) : (nameDict.value[movie], count))

ThЭто пример кода из поваренной книги для Apache Spark и Python.Все остальные упражнения на кодирование отлично работают в моем окружении.Windows 10 / Canopy / Python 3.5 / Spark 2.3.2 Я проверил транслируемый словарь, все в порядке, и уже напечатал sortedMovies RDD, который тоже в порядке.Я проверил онлайн ошибки книги, тоже ничего.

Интересно, это синтаксическая ошибка из-за версии Python или что-то в этом роде.

from pyspark import SparkConf, SparkContext

def loadMovieNames():
    movieNames = {}
    with open("ml-100k/u.item") as f:
        for line in f:
            fields = line.split('|')
            movieNames[int(fields[0])] = fields[1]
    return movieNames

conf = SparkConf().setMaster("local").setAppName("PopularMovies")
sc = SparkContext(conf = conf)

nameDict = sc.broadcast(loadMovieNames())

lines = sc.textFile("file:///SparkCourse/ml-100k/u.data")
movies = lines.map(lambda x: (int(x.split()[1]), 1))
movieCounts = movies.reduceByKey(lambda x, y: x + y)

flipped = movieCounts.map(lambda x: (x[1], x[0]))
sortedMovies = flipped.sortByKey()

sortedMoviesWithNames = sortedMovies.map(lambda (count, movie) : 
(nameDict.value[movie], count))

results = sortedMoviesWithNames.collect()

for result in results:
    print(result)

1 Ответ

0 голосов
/ 27 декабря 2018

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

sum_function = lambda a, b: a + b

Обратите внимание на отсутствующие скобки.Если вы пытаетесь сопоставить кортеж с другим кортежем, вам нужно сделать что-то вроде:

lambda tup: (nameDict.value[tup[1]], tup[0])

Функции Python не распаковывают кортежи автоматически, поэтому функция с несколькими аргументами будет не принять кортеж для своих аргументов и заставить его работать должным образом (конечно, для этого и нужен оператор *).

...