PySpark 初学者:培养中级技能

分区、洗牌、连接、缓存和执行计划的实用下一步。面向初学者的 PySpark 帖子:构建中级技能首先出现在 Towards Data Science 上。

来源:走向数据科学

在本系列的前两篇文章中,您已经涵盖了很多内容。

您知道如何创建 SparkSession、将数据加载到 DataFrame、定义架构、清理杂乱的列、连接数据集、编写 Parquet 文件以及构建简单的 PySpark 工作流程。我将在本系列的末尾放置本系列中这些文章的链接。

这已经足够做有用的工作了。但是,一旦数据增长或转换变得更加复杂,一系列新的问题就会开始出现。

  • 为什么这个作业突然变慢了?
  • 为什么一个简单的 groupBy() 花费的时间比预期的要长?
  • 为什么 PySpark 会写入这么多输出文件?
  • 什么时候应该缓存 DataFrame?
  • 洗牌到底是什么?
  • 本文介绍的是后续步骤。

    我们仍然保持友好。我们不会深入探讨集群调整、内存内部结构、Kubernetes、YARN 或晦涩的 PySpark 配置设置。相反,我们将重点关注实用的想法,帮助您了解 PySpark 的功能以及如何编写行为更可预测的 PySpark 代码。

    总体主题是:

    达到中级水平 PySpark 主要是关于理解数据移动。

    一旦这个想法被采纳,PySpark 开始变得更加可预测。 PySpark 作业表现不佳通常有充分的理由;您只需要知道去哪里寻找即可。

    当 PySpark 开始感觉缓慢时

    当你第一次学习 PySpark 时,很自然地会关注代码。

    你写的东西像:

    df.filter(df.city == "伦敦")

    df.groupBy("customer_id").sum("金额")

    df.join(客户, on="customer_id")

    但当您进入更高级的 PySpark 时,您需要开始思考 PySpark 在幕后必须做什么。
    有些操作相当便宜。过滤行就是一个很好的例子。 Spark 可以查看每一行,做出是/否决定,然后继续。

    df_london = df.filter(df.city == "伦敦")

    df_totals = df.groupBy("customer_id").sum("金额")

    所以中级习惯很简单:
    PySpark 如何分配工作
    df.rdd.getNumPartitions()8df_fewer = df.coalesce(4)