我有两个数据框,如下图:
数据框1:(df1)
+---+----------+
|id |features |
+---+----------+
|1 |[1, 2, 3] |
|2 |[4, 5, 6] |
+---+----------+
数据框2:(df2)
rdd1=df1.rdd
之后我将Df转换为Rdd
rdd1.collect()
如果我正在做[Row(id=8, f=[5, 4, 5]), Row(id=9, f=[4, 5, 2])]
rdd2=df2.rdd
broadcastedrddif = sc.broadcast(rdd2.collectAsMap())
结果如下所示
{1: [1, 2, 3], 2: [4, 5, 6]}
现在,如果我正在做broadcastedrddif.value
((8,[(1,(5*1+2*4+5*3)),(2,(5*4+4*5+5*6))]),(9,[(1,(4*1+5*2+2*3)),(2,(4*4+5*5+2*6)]) ))
现在我想做rdd1和broadcastedrddif的乘法和,即它应该返回如下的输出。
((8,[(1,28),(2,70)]),(9,[(1,20),(2,53)]))
所以我的最终输出应该是
Source 1: ---1--------3--4-----------------------------x
Source 2: -------2----------x
"merged" ---1---2----3--4--x
其中(1,28)是一个元组而不是浮点数。
请帮我解决这个问题。
答案 0 :(得分:1)
我不明白为什么你使用了sc.broadcast()
但是我还是用它...
在这种情况下,在最后一个RDD上使用mapValues非常有用,我使用列表解析来使用字典执行操作。
x1=sc.parallelize([[8,5,4,5], [9,4,5,2]]).map(lambda x: (x[0], (x[1],x[2],x[3])))
x1.collect()
x2=sc.parallelize([[1,1,2,3], [2,4,5,6]]).map(lambda x: (x[0], (x[1],x[2],x[3])))
x2.collect()
#I took immediately an RDD because is more simply to test
broadcastedrddif = sc.broadcast(x2.collectAsMap())
d2=broadcastedrddif.value
def sum_prod(x,y):
c=0
for i in range(0,len(x)):
c+=x[i]*y[i]
return c
x1.mapValues(lambda x: [(i, sum_prod(list(x),list(d2[i]))) for i in [k for k in d2.keys()]]).collect()
Out[19]: [(8, [(1, 28), (2, 70)]), (9, [(1, 20), (2, 53)])]