对于以下两种检查数据帧是否为空的方法:

  • df.isEmpty
  • df.limit(1).count == 0

  • 我看到df.isEmpty具有以下实现:
      def isEmpty: Boolean = withAction("isEmpty", limit(1).groupBy().count().queryExecution) { plan =>
        plan.executeCollect().head.getLong(0) == 0
      }
    

    看起来它不只是直接计数。
    groupBy背后的想法是什么?只是为了获取数据框?

    为什么使用queryExecution计划?

    最佳答案

    在这篇文章中,我看到了三个不同的问题。
    表演节目
    如果仔细检查源代码,您会发现 df.count 所做的groupBy与获取RelationalGroupedDateset的相同。
    因此,如果我们比较两个实现:

    def isEmpty: Boolean = withAction("isEmpty", limit(1).groupBy().count().queryExecution) {
      plan => plan.executeCollect().head.getLong(0) == 0
    }
    
    def count(): Long = withAction("count", groupBy().count().queryExecution) { plan =>
      plan.executeCollect().head.getLong(0)
    }
    
    df.isEmptydf.limit(1).count() == 0在幕后的行为完全相同。
    但是,为了清楚起见,我会选择df.isEmpty
    为什么使用queryExecution计划?
    查询执行计划是具有全局执行计划所需的属性。
    每次完成转换后,此转换都会升级queryExecution
    每次执行操作时,都会检索queryExecution,然后Catalyst计划对其进行优化。groupBy背后的想法是什么?
    count 方法创建一个带有单个组的 RelationalGroupedDataset 。然后用Literal(1)填充该组,然后同时按键减少(它不包含键,因此减少了每一列),以得到一个带有称为“count”的单列且只有一行包含count的DataFrame。 (这就是为什么在df.count实现中我们可以看到.head.getLong(0)的原因
    此实现使您可以在每个分区中同时减少数据量,而无需创建要计数的迭代器。

    09-26 21:48
    查看更多