如何使用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()