Pyspark - TypeError:使用reduceByKey

时间:2018-03-07 23:17:44

标签: python apache-spark pyspark

我的“asdasd.csv”文件具有以下结构。

 Index,Arrival_Time,Creation_Time,x,y,z,User,Model,Device,gt
0,1424696633908,1424696631913248572,-5.958191,0.6880646,8.135345,a,nexus4,nexus4_1,stand
1,1424696633909,1424696631918283972,-5.95224,0.6702118,8.136536,a,nexus4,nexus4_1,stand
2,1424696633918,1424696631923288855,-5.9950867,0.6535491999999999,8.204376,a,nexus4,nexus4_1,stand
3,1424696633919,1424696631928385290,-5.9427185,0.6761626999999999,8.128204,a,nexus4,nexus4_1,stand

好的,我得到以下{key,value}元组来操作它。

#                                 x           y        z
[(('a', 'nexus4', 'stand'), ((-5.958191, 0.6880646, 8.135345)))]
#           part A (key)               part B (value) 

我的计算均值的代码如下,我必须计算每列的平均值,每个键的X,Y Z.

rdd_ori = sc.textFile("asdasd.csv") \
        .map(lambda x: ((x.split(",")[6], x.split(",")[7], x.split(",")[9]),(float(x.split(",")[3]),float(x.split(",")[4]),float(x.split(",")[5]))))

meanRDD = rdd_ori.mapValues(lambda x: (x,1)) \
            .reduceByKey(lambda a, b: (a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2], a[1] + b[1]))\
            .mapValues(lambda a : (a[0]/a[3], a[1]/a[3],a[2]/a[3]))

我的问题我尝试了那段代码,它在其他PC上工作正常,我用它来开发它(PySpark Py3)

这是一个例子,这段代码是正确的:

enter image description here

但我不知道为什么我会收到此错误,重要的部分是

  
    

----------------------------------------------- ---------------------------- Py4JJavaError Traceback(最近的电话     最后)in()           9#sum_1 = count_.reduceByKey(lambda x,y:(x [0] [0] + y [0] [0],x 0 + y 0,x [0] [2 ] + Y [0] [2]))          10     ---> 11印刷(meanRDD.take(1))

  
     

/opt/spark/current/python/pyspark/rdd.py in take(self,num)1341
  1342 p =范围(partsScanned,min(partsScanned +   numPartsToTry,totalParts))    - > 1343 res = self.context.runJob(self,takeUpToNumLeft,p)1344 1345 items + = res

     runJob中的

/opt/spark/current/python/pyspark/context.py(self,rdd,   partitionFunc,partitions,allowLocal)       990#SparkContext#runJob。       991 mappedRDD = rdd.mapPartitions(partitionFunc)    - > 992 port = self._jvm.PythonRDD.runJob(self._jsc.sc(),mappedRDD._jrdd,partitions)       993返回列表(_load_from_socket(port,mappedRDD._jrdd_deserializer))       994

     

/opt/spark/current/python/lib/py4j-0.10.4-src.zip/py4j/java_gateway.py   在调用(self,* args)1131 answer =   self.gateway_client.send_command(command)1132 return_value   = get_return_value(    - > 1133回答,self.gateway_client,self.target_id,self.name)1134 1135 for temp_arg in temp_args:

     deco中的

/opt/spark/current/python/pyspark/sql/utils.py(* a,** kw)        61 def deco(* a,** kw):        62尝试:   ---> 63返回f(* a,** kw)        64除了py4j.protocol.Py4JJavaError为e:        65 s = e.java_exception.toString()

     

/opt/spark/current/python/lib/py4j-0.10.4-src.zip/py4j/protocol.py in   get_return_value(answer,gateway_client,target_id,name)       317引发Py4JJavaError(       318“调用{0} {1} {2}时发生错误。\ n”。    - > 319格式(target_id,“。”,名称),值)       320其他:       321提出Py4JError(

     

Py4JJavaError:调用时发生错误   Z:org.apache.spark.api.python.PythonRDD.runJob。 :   org.apache.spark.SparkException:作业因阶段失败而中止:   阶段127.0中的任务0失败1次,最近失败:丢失任务   阶段127.0中的0.0(TID 102,localhost,执行程序驱动程序):org.apache.spark.api.python.PythonException:Traceback(最新版本)   最后打电话):文件   “/opt/spark/current/python/lib/pyspark.zip/pyspark/worker.py”,一行   177,主要       process()文件“/opt/spark/current/python/lib/pyspark.zip/pyspark/worker.py”,行   172,正在进行中       serializer.dump_stream(func(split_index,iterator),outfile)文件“/opt/spark/current/python/pyspark/rdd.py”,第2423行,in   pipeline_func       return func(split,prev_func(split,iterator))文件“/opt/spark/current/python/pyspark/rdd.py”,第2423行,in   pipeline_func       return func(split,prev_func(split,iterator))文件“/opt/spark/current/python/pyspark/rdd.py”,第346行,在func中       return f(iterator)File“/opt/spark/current/python/pyspark/rdd.py”,1842行,in   combineLocally       merger.mergeValues(iterator)File“/opt/spark/current/python/lib/pyspark.zip/pyspark/shuffle.py”,line   238,在mergeValues中        d [k] = comb(d [k],v)如果k in d else creator(v)File“”,第3行,在TypeError中:   'float'对象不可订阅

1 个答案:

答案 0 :(得分:3)

继承人reduceByKey的工作原理。我将以您的示例为例,即您传递给reduceByKey

的以下数据
#                                 x           y        z
[(('a', 'nexus4', 'stand'), ((-5.958191, 0.6880646, 8.135345), 1))]
#           part A (key)               part B (value)       counter

让我一步一步走

执行以下mapValues功能

rdd_ori.mapValues(lambda x: (x,1))

rdd数据将显示为

((u'a', u'nexus4', u'stand'), ((-5.9427185, 0.6761626999999999, 8.128204), 1))
((u'a', u'nexus4', u'stand'), ((-5.958191, 0.6880646, 8.135345), 1))
((u'a', u'nexus4', u'stand'), ((-5.95224, 0.6702118, 8.136536), 1))
((u'a', u'nexus4', u'stand'), ((-5.9950867, 0.6535491999999999, 8.204376), 1))

所以当reduceByKey被调用为

.reduceByKey(lambda a, b: (a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2], a[1] + b[1]))

并且对具有相同键的所有行进行分组,并将值传递给lambda reducyByKey函数。

由于在您的情况下,所有键都相同,因此在以下迭代中将值传递给ab变量。

在第一次迭代中,a((-5.9427185, 0.6761626999999999, 8.128204), 1)b((-5.958191, 0.6880646, 8.135345), 1),因此计算部分(a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2], a[1] + b[1])是正确的并且已通过。

在第二次迭代中,a(a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2], a[1] + b[1])的输出,(-11.910430999999999, 1.3582764, 16.271881, 2)

因此,如果您查看数据的格式,a[0][0]中就没有a。您可以获得a[0]a[1] ..等等。这就是问题所在。这就是错误信息所暗示的内容

  
    

TypeError:' float'对象不可订阅

  

此解决方案是格式化数据,以便您可以a访问a[0][0],如果您格式化以下格式的reduceByKey,则可以执行此操作。< /强>

.reduceByKey(lambda a, b: ((a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2]), a[1] + b[1]))

但这会给您的上一个mapValues功能

带来麻烦
.mapValues(lambda a : (a[0]/a[3], a[1]/a[3],a[2]/a[3]))

作为你的价值,即。 lambda函数中的a ,属于((-23.848236199999995, 2.6879882999999998, 32.604461), 4),因此a[0]表示(-23.848236199999995, 2.6879882999999998, 32.604461)a[1]表示4,并且没有mapValues不再这样你会遇到

  
    

IndexError:元组索引超出范围

  

所以你的上一个.mapValues(lambda a : (a[0][0]/a[1], a[0][1]/a[1],a[0][2]/a[1])) 应该是

rdd_ori = sc.textFile("asdasd.csv") \
    .map(lambda x: ((x.split(",")[6], x.split(",")[7], x.split(",")[9]),(float(x.split(",")[3]),float(x.split(",")[4]),float(x.split(",")[5]))))

meanRDD = rdd_ori.mapValues(lambda x: (x, 1)) \
    .reduceByKey(lambda a, b: ((a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2]), a[1] + b[1]))\
    .mapValues(lambda a : (a[0][0]/a[1], a[0][1]/a[1],a[0][2]/a[1]))

总体而言,以下代码应该适合您

f1

我希望我已经解释得很好。