2017-06-22 41 views
0

目的是通过输入值(它是一个json文件)对键值进行排序。我有4种方法,两对映射器和减速器。Mapreduce无法按值排序[python]

输入类似于

{ 
    id: 1, 
    user: { 
    friends_count: 1 
    } 
} 

输出变换器和减速的第一阶段是一样的东西

A 1 
B 2 
C 3 
D 4 

我要的是

1 A 
2 B 
3 C 
4 D 

在第一阶段排序关键工作正常,但在第二阶段,我试图使价值的关键,引发错误的说

TypeError: at 0x7fa43ea615a0> is not JSON serializable

其中我使用的代码是

from mrjob.job import MRJob 
from mrjob.step import MRStep 
import json 

class MRFrnsCounter(MRJob): 
    def steps(self): 
     return [ 
      MRStep(mapper=self.mapper, 
        reducer=self.reducer), 
      MRStep(mapper = self.mapper_two, 
        reducer = self.reducer_two) 
     ] 

def mapper(self, _, line): 
    f = json.loads(line) 
    (uid, frns) = f["id"],f["user"]["friends_count"] 
    yield (uid), (frns) 

def reducer(self, uid, frns): 
    yield uid, sum(frns) 

def mapper_two(self, uid, frns): 
    yield (frns), (uid) 

def reducer_two(self, frns, uid): 
    yield (frns), uid 

if __name__ == '__main__': 
    MRFrnsCounter.run() 

在第二映射器的码符时的键和值是相反的。任何意见将不胜感激。

+0

是这样的:TypeError:在0x7fa43ea615a0不是JSON序列化真的完整的错误信息? –

+0

对不起。完整的错误消息是 ** TypeError:<生成器对象 at 0x7efbfe824a50>不是JSON可串行化** – Sid

+0

发布带有堆栈跟踪的完整错误消息。什么是'线'?我很确定你需要在'mapper'中实现这个生成器。 –

回答

0

为什么不只是yield sum(frns), uid在第一个减速机?

但是,在您的第二个映射器中,您试图产生一个生成器,而不是一个整数。遍历发电机产生frns,uid。这样的事情:

for num in frns: 
    yield num, uid 
+0

我厌倦了,但我在某处看到,在第二阶段应该发生逆转键。但是,我提出了同样的错误。 – Sid

+0

在mapper_two中,您试图产生不是json序列化的generator对象。你需要遍历发生器以产生frns,uid。看到上面的编辑。 – Bill

+0

我改变所述第二减速器 'DEF reducer_two(个体,浮动利率,UID): 在浮动利率民: 收率NUM,uid' 但现在它引发错误 **类型错误:“诠释'object is not iterable ** – Sid