开发者社区> 问答> 正文

PySpark - 计算公共元素的更有效方法

我有两个dataframes,说dfA和dfB。
我想取他们的交叉点,然后计算该user_ids交叉点中唯一的数量。

我尝试了以下非常慢的速度,它崩溃了很多:

dfA.join(broadcast(dfB), ['user_id'], how='inner').select('user_id').dropDuplicates().count()
我需要运行许多这样的线,以获得一个情节。

如何以有效的方式执行此类查询?

展开
收起
社区小助手 2018-12-19 17:08:47 1457 0
1 条回答
写回答
取消 提交回答
  • 社区小助手是spark中国社区的管理员,我会定期更新直播回顾等资料和文章干货,还整合了大家在钉群提出的有关spark的问题及回答。

    我认为您可以先选择必要的列,然后再执行连接。在连接之前移动dropDuplicates也应该是有益的,因为那时你摆脱了在其中一个数据帧中出现多次的user_ids。

    生成的查询可能如下所示:

    dfA.select("user_id").join(broadcast(dfB.select("user_id")), ['user_id'], how='inner')\

    .select('user_id').dropDuplicates().count()

    要么:

    dfA.select("user_id").dropDuplicates(["user_id",]).join(broadcast(dfB.select("user_id")\

    .dropDuplicates(["user_id",])), ['user_id'], how='inner').select('user_id').count()

    或者具有distinct的版本也可以使用。

    dfA.select("user_id").distinct().join(broadcast(dfB.select("user_id").distinct()),\

    ['user_id'], how='inner').select('user_id').count()
    

    如问题中所述,数据框的唯一相关部分是列user_id(在您的问题中,您描述了您加入user_id,之后仅使用该user_id字段)

    当您只需要每个数据帧中一列的不同值时,性能问题的根源就是连接两个大数据帧。

    为了提高性能,我会做以下事情:

    创建两个小DF,它们只保存user_id每个数据帧的列。
    这将大大减少每个数据帧的大小,因为它只能保存一列(唯一相关的列)

    dfAuserid = dfA.select("user_id")
    dfBuserid = dfB.select("user_id")
    获取distinct(注意:它相当于dropDuplicate()每个数据帧的值)
    这将大大减少每个数据帧的大小,因为每个新数据帧只包含列的不同值user_id。

    dfAuseridDist = dfA.select("user_id").distinct()
    dfBuseridDist = dfB.select("user_id").distinct()
    join对上述两个极简主义数据帧执行以获取交集中的唯一值

    2019-07-17 23:23:04
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
《Apache Flink-重新定义计算》PDF下载 立即下载
# Apache Spark系列技术直播# 第五讲【 Spark RDD编程入门 】 立即下载
Apache Flink 流式应用中状态的数据结构定义升级 立即下载