哪种方法最好检查数据帧是否为空?`df.limit(1).count == 0`或`df.isEmpty`?

apn*_*ith 9 scala apache-spark apache-spark-sql

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

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

我看到df.isEmpty有以下实现:

  def isEmpty: Boolean = withAction("isEmpty", limit(1).groupBy().count().queryExecution) { plan =>
    plan.executeCollect().head.getLong(0) == 0
  }
Run Code Online (Sandbox Code Playgroud)

看起来它不只是直接计数。

其背后的想法是groupBy什么?只是为了获取数据框?

为什么要queryExecution使用该计划?

Blu*_*ken 11

在这篇文章中,我看到了三个不同的问题。

表演节目

如果仔细检查源代码,则可以看到获得RelationalGroupedDatesetdf.count的功能相同groupBy

因此,如果我们比较两个实现:

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)
}
Run Code Online (Sandbox Code Playgroud)

df.isEmpty并且df.limit(1).count() == 0在幕后行为完全相同。

但是,我会为df.isEmpty清楚起见而去。

为什么queryExecution使用该计划?

查询执行计划是具有全局执行计划所需的属性。

每次完成转换后,queryExecution都会使用此转换升级。

每次执行操作时,queryExecution都会检索,然后Catalyst计划对其进行优化。

其背后的想法是groupBy什么?

count方法RelationalGroupedDataset使用单个组创建一个。然后将该组填充Literal(1)并按键减少(它不包含键,因此减少了每一列),以同时获得一个DataFrame称为“ count”的单列,其中只有一行包含count。(这就是为什么在df.count实现中我们可以看到一个.head.getLong(0)

此实现使您可以在每个分区中同时减少,而无需创建要计数的迭代器。