Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python中的mrjob将Reduce端连接作为Map Reduce作业_Python_Hadoop_Join_Mapreduce_Mrjob - Fatal编程技术网

如何使用Python中的mrjob将Reduce端连接作为Map Reduce作业

如何使用Python中的mrjob将Reduce端连接作为Map Reduce作业,python,hadoop,join,mapreduce,mrjob,Python,Hadoop,Join,Mapreduce,Mrjob,我有两个数据集要合并,即交易数据集和合同数据集,我想在其中使用地址分别to_address作为连接属性,值的属性 contract dataset fields: address, is_erc20, is_erc721, block_number, block_timestamp transactions dataset fields: block_number, from_address, to_address, value, gas, gas_price, timestamp 所以

我有两个数据集要合并,即
交易
数据集和
合同
数据集,我想在其中使用
地址
分别
to_address
作为连接属性,值的
属性

contract dataset fields: 
address, is_erc20, is_erc721, block_number, block_timestamp

transactions dataset fields: 
block_number, from_address, to_address, value, gas, gas_price, timestamp
所以我要做的是创建一个输出为:
address,value

例如:

transactions dataset: 
to_address        value
0x412270b1f0f3884 240648550000000000
0x8d5a0a7c555602f 984699000000000000

contract dataset:
address
0x412270b1f0f3884

the output should be:
to_address        value
0x412270b1f0f3884 240648550000000000

as 0x8d5a0a7c555602f is not present in the contract dataset. 
下面是我的代码,我不确定我做错了什么。有什么帮助吗

from mrjob.job import MRJob

class repartition_join(MRJob):

    def mapper(self, _, line):
        try:
            if(len(line.split(','))==5): #contracts dataset
                fields=line.split(',')
                join_key=fields[0] #key is address
                yield (join_key, 1) #yield join key given id 1?
            elif(len(line.split(','))==7): #transactions dataset
                fields=line.split(',')
                join_key=fields[2] #to_address, which is the key
                join_value=int(fields[3]) #[3] = value
                yield (join_key,(join_value,2)) #gives key with value
        except:
            pass

    def reducer(self, key, values):
      val = None
        for value in values:
            if value[1] == 2:
                val = (value[0])
        yield(key, val)
 

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

再次考虑用于reduce侧连接的map reduce管道。看起来你很难理解它

为了将键值对与两个关系区分开来,必须向映射器产生的值添加关系符号。 假设您想要进行内部联接,只有当您的
契约
事务
数据集中存在一个元组时,您才能在reducer中为Reduce端联接生成一个元组。因此,必须将这些关系的元组保存在单独的列表中,并通过关系符号标识元组。这可以很容易地针对其他连接进行调整,例如(左/右/全)外部连接、半/反连接

在下面的示例中,我将关系符号
'C'
用于
合同
,将
'T'
用于
交易
数据集。我无法亲自尝试,因为我缺少数据集,但它应该是这样工作的。如果您有任何问题,请告诉我并发表评论

我可以建议您看看“MapReduce设计模式”一书 Donald Miner,Adam Shake“因为它还解释了Map Reduce任务的常见连接算法。还可以查看最新的

从mrjob.job导入mrjob
从mrjob.step导入MRStep
类重新分区\u加入(MRJob):
def映射器(自身、线):
字段=行。拆分(“,”)
如果len(字段==5):#合同数据集
join_key=fields[0]#key位于属性地址中
yield(join_key,('C',1))#yield join key,未使用值
elif len(字段)==7:#事务数据集
join_key=字段[2]#key位于_address的属性中
join_value=int(字段[3])#值位于属性值中
yield(join_key,('T',join_value))#产生带值的join key
其他:
pass#TODO处理错误
def减速器(自身、键、值):
地址=键#连接键
合同\元组=[]
事务\u元组=[]
对于值中的值:
关系_symbol=值[0]#“T”或“C”
如果关系_symbol=='C':#合同数据集
contracts_tuples.append(值[1])#始终为1-只需知道contracts中有一个元组
elif关系_symbol=='T':#事务数据集
事务_tuples.append(值[1])#在value属性中追加值
其他:
pass#TODO处理错误
#内部连接契约和事务,必要时进行概括
如果len(合同组)>0且len(交易组)>0:
对于事务组中的值:
收益率(地址、值)
def步骤(自我):
返回[MRStep](
mapper=self.mapper,
减速器=自减速器)
]
如果“名称”=“\uuuuuuuu主要”:
重新分区\u join.run()