使用多个密钥加入两个数据框

时间:2017-02-26 18:27:25

标签: join apache-spark dataframe pyspark rdd

我有两个数据帧,一个带有id和随机值,第二个带有id和值的元组。 我想用我在第一个数据帧中生成的相应随机值替换id的元组。 我编码了但结果并不好。

实施例

id2word=sc.parallelize([(1),(2),(3)])

def build_data(j):
  a=random.uniform(-0.5,0.5)
  return (j,a)

rdd1 = id2word.map(build_data).toDF(['id_word','value'])

+-------+-------------------+
|id_word|              value|
+-------+-------------------+
|      1| 0.4651491097313888|
|      2|0.32978333933864534|
|      3|0.32978333933864534|
+-------+-------------------+

rdd2 = sc.parallelize([(1,2,1), (1,3, 0), (2,3,1)]).toDF(['id_main','id_context','coocur'])

+-------+----------+------+
|id_main|id_context|coocur|
+-------+----------+------+
|      1|         2|     1|
|      1|         3|     0|
|      2|         3|     1|
+-------+----------+------+

目标是将id_main值和id_context值替换为rdd1中定义的id_word值。 我使用连接来实现它,但结果根本不连贯。我不明白为什么

df=rdd1.join(rdd2,rdd1.id_word==rdd2.id_main).select(rdd2.id_context,rdd1.value,rdd2.coocur)
df2=rdd1.join(df,df.id_context==rdd1.id_word)

这是我的结果并且没有好处,因为对于coocur 0我应该得到id_word = 1(0.4651491097313888)和id_word = 3(0.32978333933864534)的值而不是我有0.32978333933864534和0.32978333933864534

+-------------------+-------------------+------+
|              value|              value|coocur|
+-------------------+-------------------+------+
|0.32978333933864534|0.32978333933864534|     0|
|0.32978333933864534|0.32978333933864534|     1|
| 0.4651491097313888| 0.4651491097313888|     1|
+-------------------+-------------------+------+

1 个答案:

答案 0 :(得分:0)

我认为你两次拉出同一列“价值”。为了安全起见,我将使用“id_main”和“id_context”的值列别名,并且它们按预期工作。

>>> def build_data(j):
...    import random
...    a=random.uniform(-0.5,0.5)
...    return (j,a)
...
>>> rdd1 = sc.parallelize(map(lambda x: build_data(x) ,range(1,4))).toDF(['id_word','value'])
>>> rdd2 = sc.parallelize([(1,2,1), (1,3, 0), (2,3,1)]).toDF(['id_main','id_context','coocur'])
>>> temp = rdd2.join(rdd1, rdd2.id_main == rdd1.id_word).select(rdd1.value.alias('id_main'),rdd2.id_context,rdd2.coocur)
>>> result = temp.join(rdd1, temp.id_context == rdd1.id_word).select(temp.id_main, rdd1.value.alias('id_context'), rdd2.coocur)

>>> rdd1.show()
+-------+--------------------+
|id_word|               value|
+-------+--------------------+
|      1| 0.14148875937228922|
|      2| 0.22399596259278198|
|      3|-0.10276714457192437|
+-------+--------------------+

>>> result.show()
+-------------------+--------------------+------+
|            id_main|          id_context|coocur|
+-------------------+--------------------+------+
|0.14148875937228922|-0.10276714457192437|     0|
|0.22399596259278198|-0.10276714457192437|     1|
|0.14148875937228922| 0.22399596259278198|     1|
+-------------------+--------------------+------+