Python中RDD调用map+sortByKey报错:'list'对象无map属性
问题分析与解决方案
这个错误AttributeError: 'list' object has no attribute 'map'的核心原因很直白:你把一个普通Python列表当成了Apache Spark的RDD对象来使用了。虽然你给变量起名叫RDD,但它本质是Python原生的list,而list并没有Spark RDD特有的map()方法。
除此之外,你的欧几里得距离计算代码还有两个小错误需要修正:
- 在Python中,
^是按位异或运算符,不是平方运算,计算平方应该用**2 - 代码里的
x[1][i][1]是错误的,x[1]是一维列表(比如[1,2,3]),x[1][i]已经是单个数值,不存在第二个索引[1]
下面分两种场景给出解决代码:
场景1:你确实需要使用Spark RDD处理数据
如果是要基于Spark进行分布式计算,你需要先初始化Spark环境,再把普通列表转换成Spark RDD:
import math from pyspark.sql import SparkSession # 初始化SparkSession(Spark 2.0+推荐用这个替代SparkContext) spark = SparkSession.builder.appName("EuclideanDistanceCalc").getOrCreate() sc = spark.sparkContext # 将普通列表转换为Spark RDD rdd = sc.parallelize([(0, [1,2,3], 2),(1, [2,3,4], 4),(2, [4,5,6], 6),(3, [6,7,8], 8)]) dados = [4,5,6] # 修正后的欧几里得距离计算与排序 teste_euclidiana = rdd.map(lambda x: ( x[0], [math.sqrt((x[1][i] - dados[i])**2) for i in range(len(dados))], x[2] )).sortByKey() # 打印结果(collect()将分布式RDD拉取到本地) print(teste_euclidiana.collect()) # 记得关闭SparkSession spark.stop()
场景2:不需要Spark,只用普通Python处理
如果只是本地小数据处理,直接用Python内置的map()函数和sorted()即可:
import math data_list = [(0, [1,2,3], 2),(1, [2,3,4], 4),(2, [4,5,6], 6),(3, [6,7,8], 8)] dados = [4,5,6] # 用内置map处理数据,再按key排序 teste_euclidiana = sorted( map(lambda x: ( x[0], [math.sqrt((x[1][i] - dados[i])**2) for i in range(len(dados))], x[2] ), data_list), key=lambda item: item[0] ) print(teste_euclidiana)
内容的提问来源于stack exchange,提问作者Pablo Luiz Leon
相关产品推荐
相关产品推荐

