如何检查spark数据帧是否为空

aux*_*xdx 82 apache-spark apache-spark-sql

现在,我必须用来df.count > 0检查它是否DataFrame为空.但它效率低下.有没有更好的方法来做到这一点.

谢谢.

PS:我想检查它是否为空,以便我只保存,DataFrame如果它不是空的

hul*_*003 118

对于Spark 2.1.0,我的建议是使用head(n: Int)take(n: Int)使用isEmpty,无论哪个人有最明确的意图.

df.head(1).isEmpty
df.take(1).isEmpty
Run Code Online (Sandbox Code Playgroud)

与Python等价:

len(df.head(1)) == 0  # or bool(df.head(1))
len(df.take(1)) == 0  # or bool(df.take(1))
Run Code Online (Sandbox Code Playgroud)

如果DataFrame为空,则使用df.first()df.head()将返回java.util.NoSuchElementException.直接first()打电话head(),打电话head(1).head.

def first(): T = head()
def head(): T = head(1).head
Run Code Online (Sandbox Code Playgroud)

head(1)返回一个数组,因此接受head该数组导致java.util.NoSuchElementExceptionDataFrame为空时.

def head(n: Int): Array[T] = withAction("head", limit(n).queryExecution)(collectFromPlan)
Run Code Online (Sandbox Code Playgroud)

因此,不是直接调用head(),而是head(1)直接使用来获取数组,然后就可以使用了isEmpty.

take(n)也相当于head(n)......

def take(n: Int): Array[T] = head(n)
Run Code Online (Sandbox Code Playgroud)

limit(1).collect()相当于head(1)(通知limit(n).queryExecutionhead(n: Int)方法),所以下面都是等价的,至少从我可以告诉,你就不必赶java.util.NoSuchElementException异常,当数据框为空.

df.head(1).isEmpty
df.take(1).isEmpty
df.limit(1).collect().isEmpty
Run Code Online (Sandbox Code Playgroud)

我知道这是一个较旧的问题,所以希望它可以帮助使用更新版Spark的人.

  • 对于那些使用pyspark的人.isEmpty不是一件事.请改为len(d.head(1))> 0. (12认同)
  • 为什么这比`df.rdd.isEmpty`更好? (3认同)
  • df.head(1).isEmpty 花费了大量时间是否有其他优化解决方案。 (3认同)
  • 嘿@Rakesh Sabbani,如果“df.head(1)”花费了大量时间,那么“可能”是因为您的“df”执行计划正在执行一些复杂的操作,从而阻止 Spark 走捷径。例如,如果您只是从 parquet 文件中读取“df = Spark.read.parquet(...)”,我很确定 Spark 只会读取一个文件分区。但是,如果您的“df”正在执行聚合等其他操作,则您可能会无意中强制 Spark 读取和处理大部分(如果不是全部)源数据。 (2认同)
  • 只是向 AVOID 报告我的经历:我天真地使用了 `df.limit(1).count()`。在大数据集上,它比 @hulin003 报告的示例花费更多的时间,这几乎是瞬时的 (2认同)

Jus*_*ony 40

我会说只是抓住潜在的RDD.在斯卡拉:

df.rdd.isEmpty
Run Code Online (Sandbox Code Playgroud)

在Python中:

df.rdd.isEmpty()
Run Code Online (Sandbox Code Playgroud)

话虽如此,所有这一切都是召唤take(1).length,所以它会像Rohan回答的那样做......也许稍微更明确一些?

  • 不要将df转换为RDD.它减缓了这个过程.如果你转换它会将整个DF转换为RDD并检查它是否为空.想想DF是否有数百万行,转换为RDD本身需要花费大量时间. (24认同)
  • 在我的情况下,这比df.count()== 0慢得多 (6认同)
  • 转换为 rdd 不是一项繁重的任务吗? (3认同)
  • .rdd这么过程减慢了很多 (3认同)

aNa*_*ame 16

我有同样的问题,我测试了 3 个主要解决方案:

  1. (df != null) && (df.count > 0)
  2. df.head(1).isEmpty() 正如@hulin003 建议的那样
  3. df.rdd.isEmpty() 正如@Justin Pihony 所建议的那样

当然,这 3 个工作,但是就性能而言,这是我发现的,当在我的机器上的同一个 DF 上执行这些方法时,就执行时间而言:

  1. 大约需要 9366 毫秒
  2. 需要~5607ms
  3. 大约需要 1921 毫秒

因此我认为最好的解决方案是df.rdd.isEmpty()@Justin Pihony 建议的

  • 出于好奇...这是用什么大小的 DataFrame 进行测试的? (4认同)
  • 我已经测试了 1000 万行...并且得到了与 df.count() 或 df.rdd.isEmpty() 相同的时间 (2认同)

Roh*_*tty 13

您可以利用head()(或first())函数来查看是否DataFrame有一行.如果是这样,它不是空的.

  • 如果dataframe为空,则抛出"java.util.NoSuchElementException:next on empty iterator"; [Spark 1.3.1] (10认同)

Ber*_*ium 13

从 Spark 2.4.0 开始,有Dataset.isEmpty.

它的实现是:

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

请注意, aDataFrame不再是 Scala 中的类,它只是一个类型别名(可能随 Spark 2.0 更改):

type DataFrame = Dataset[Row]
Run Code Online (Sandbox Code Playgroud)


小智 13

PySpark 3.3.0+ / Scala 2.4.0+

df.isEmpty()
Run Code Online (Sandbox Code Playgroud)

  • 在 PySpark 中,仅从 3.3.0 版本开始引入 (3认同)

Ade*_*ner 7

如果您使用 Pyspark,您还可以执行以下操作:

len(df.head(1)) > 0
Run Code Online (Sandbox Code Playgroud)


Abd*_*heb 6

对于 Java 用户,您可以在数据集上使用它:

public boolean isDatasetEmpty(Dataset<Row> ds) {
        boolean isEmpty;
        try {
            isEmpty = ((Row[]) ds.head(1)).length == 0;
        } catch (Exception e) {
            return true;
        }
        return isEmpty;
}
Run Code Online (Sandbox Code Playgroud)

这将检查所有可能的情况(空、空)。


Nan*_*ore 5

如果可以的话df.count > 0。它获取所有执行程序中所有分区的计数,并将其累加到Driver中。当您处理数百万行时,这需要一段时间。

最好的方法是执行df.take(1)并检查其是否为空。这样可以java.util.NoSuchElementException更好地进行尝试df.take(1)

完成后,数据框返回错误,take(1)而不是空行。我已经突出显示了引发错误的特定代码行。

在此处输入图片说明

  • 我也是这么说的,我不确定你为什么不赞成。 (2认同)