Spark数据框左连接应在默认行中添加具有默认行的连接,而不是右侧的空

时间:2019-07-30 18:37:28

标签: apache-spark pyspark apache-spark-sql left-join

我试图将Pyspark中的两个数据框放在一个公共列上。如果在正确的数据框中不存在common列的值,则插入空值。我希望它与正确数据框中的默认行连接,而不是空值。有可能做到这一点吗?

df1 = df1.join(df2, [df1.id == df2.channel_id], "left")
df1.select('channel_id', 'channel_name').show()

我的代码显示null,对于不匹配的行,显示null。相反,我希望它与ID = 0的行匹配,这是默认值。

1 个答案:

答案 0 :(得分:0)

  1. 这可能是实现所需目标的一种方式。

(1)首先,我们创建2个示例数据框架,然后left加入它们以获取df_join

df1 = spark.createDataFrame([(1,'a'), (2,'b'),(3, 'f'),(4,'c'),(5, 'd')], ['id', 'name1'])
df2 = spark.createDataFrame([(1,'aaa'), (2,'bb'),(7, 'ff'),(4,'cc'),(8,'mm'), (10,'kk')], ['channel_id', 'channel_name'])
df1.show()
df2.show()
df_join = df1.join(df2, [df1.id == df2.channel_id], "left")
df_join.orderBy('id').show()

数据帧如下所示。您可以看到id中不存在带有df2 3和5的行,因此它们在列channel_idchannel_name中的对应值为null。我们想用id==1行中的相应值来填充它们。

------ df1 ------
+---+-----+
| id|name1|
+---+-----+
|  1|    a|
|  2|    b|
|  3|    f|
|  4|    c|
|  5|    d|
+---+-----+

------ df2 ------
+----------+------------+
|channel_id|channel_name|
+----------+------------+
|         1|         aaa|
|         2|          bb|
|         7|          ff|
|         4|          cc|
|         8|          mm|
|        10|          kk|
+----------+------------+

------ df_join ------
+---+-----+----------+------------+
| id|name1|channel_id|channel_name|
+---+-----+----------+------------+
|  1|    a|         1|         aaa|
|  2|    b|         2|          bb|
|  3|    f|      null|        null|
|  4|    c|         4|          cc|
|  5|    d|      null|        null|
+---+-----+----------+------------+

(2)接下来,选择要使用的默认行,这里我仅将行与id==1一起使用。

default_row = df_join.where(df_join['id']==1).select('channel_id', 'channel_name').take(1)[0].asDict()
print('----- default_row: {} ------'.format(default_row))

输出显示我们将使用的默认值:

----- default_row: {'channel_id': 1, 'channel_name': 'aaa'} ------

(3)现在我们可以在每一列上使用fillna填充所有Null

for k, v in default_row.items():
    df_join = df_join.fillna(v, subset=k)
df_join.orderBy('id').show()

最终的DataFrame如下所示。空值已成功填充。

+---+-----+----------+------------+
| id|name1|channel_id|channel_name|
+---+-----+----------+------------+
|  1|    a|         1|         aaa|
|  2|    b|         2|          bb|
|  3|    f|         1|         aaa|
|  4|    c|         4|          cc|
|  5|    d|         1|         aaa|
+---+-----+----------+------------+