用两个参数的lambda函数映射的Spark RDD有什么问题?

时间:2018-12-26 21:32:30

标签: python lambda pyspark rdd

目标#

  • 打印带有电影名称和被评级次数的数据集。
  • 这是获取最受欢迎的电影的简单方法

数据

  • 一个名为“ u.data”的文件,带有movieID,userID,评分,时间戳
  • 一个名为“ u.item”的文件,其中包含movieID和电影名称以及有关每部电影的信息

方法

  • 创建字典键= MovieID,值= u.item文件中的名称
  • 将字典广播到集群上的执行者节点
  • 在每行上使用MovieID和1创建一个rdd
  • 通过movieID减少此rdd并将每个加起来
  • 翻转键(电影ID)和值(总计)以按此总数对数据集进行排序

问题

  • 然后我应该将movieID与广播的字典映射,但是在这一行上出现语法错误:
    sortedMoviesWithNames = sortedMovies.map(lambda (count, movie) : (nameDict.value[movie], count))

此代码示例摘自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 :(得分:1)

我相信带有多个参数的lambda的正确语法是:

sum_function = lambda a, b: a + b

请注意缺少的括号。 如果您试图将一个元组映射到另一个元组,则需要执行以下操作:

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

Python函数不会自动解压缩元组,因此多参数函数将接受其元组的参数并使其正常工作(当然,这就是*运算符的作用)。