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

时间:2015-09-22 02:52:55

标签: apache-spark apache-spark-sql

现在,我必须使用df.count > 0检查DataFrame是否为空。但它效率低下。有没有更好的方法呢。

感谢。

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

16 个答案:

答案 0 :(得分:92)

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

df.head(1).isEmpty
df.take(1).isEmpty

与Python等效:

len(df.head(1)) == 0  # or bool(df.head(1))
len(df.take(1)) == 0  # or bool(df.take(1))

如果DataFrame为空,则使用df.first()df.head()都会返回java.util.NoSuchElementExceptionfirst()直接调用head(),调用head(1).head

def first(): T = head()
def head(): T = head(1).head

head(1)会返回一个数组,因此当DataFrame为空时,在该数组上使用head会导致java.util.NoSuchElementException

def head(n: Int): Array[T] = withAction("head", limit(n).queryExecution)(collectFromPlan)

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

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

def take(n: Int): Array[T] = head(n)

并且limit(1).collect()相当于head(1)limit(n).queryExecution方法中的注意head(n: Int)),所以以下内容都是等效的,至少从我能说的内容来看,当DataFrame为空时,您不必捕获java.util.NoSuchElementException异常。

df.head(1).isEmpty
df.take(1).isEmpty
df.limit(1).collect().isEmpty

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

答案 1 :(得分:40)

我想说的是抓住潜在的df.rdd.isEmpty 。在斯卡拉:

df.rdd.isEmpty()
Python中的

take(1).length

话虽如此,所有这一切都是致电RewriteEngine on RewriteRule ^admin/(.*)$ backend/$1 [L] RewriteRule ^(.*)$ frontend/$1 [L] ,所以它会像Rohan回答的那样做......也许稍微更明确一点?

答案 2 :(得分:13)

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

答案 3 :(得分:5)

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

执行此操作的最佳方法是执行df.take(1)并检查其是否为空。这将返回java.util.NoSuchElementException,以便更好地尝试df.take(1)

take(1)完成而不是空行时,数据帧会返回错误。我突出显示了它抛出错误的特定代码行。

enter image description here

答案 4 :(得分:4)

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

  1. df!= null df.count> 0
  2. df.head(1).isEmpty()为@ hulin003建议
  3. df.rdd.isEmpty,如@Justin Pihony建议

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

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

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

答案 5 :(得分:3)

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

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

这会检查所有可能的情况(空,空)。

答案 6 :(得分:1)

在Scala中,您可以使用隐含添加方法isEmpty()nonEmpty()到DataFrame API,这将使代码更好阅读。

object DataFrameExtensions {
  implicit def extendedDataFrame(dataFrame: DataFrame): ExtendedDataFrame = 
    new ExtendedDataFrame(dataFrame: DataFrame)

  class ExtendedDataFrame(dataFrame: DataFrame) {
    def isEmpty(): Boolean = {
      Try{dataFrame.first.length != 0} match {
        case Success(_) => false
        case Failure(_) => true 
      }
    }

    def nonEmpty(): Boolean = !isEmpty
  }
}

这里也可以添加其他方法。要使用隐式转换,请在要使用扩展功能的文件中使用import DataFrameExtensions._。之后,这些方法可以直接使用:

val df: DataFrame = ...
if (df.isEmpty) {
  // Do something
}

答案 7 :(得分:1)

如果您使用的是Pypsark,也可以这样做:

len(df.head(1)) > 0

答案 8 :(得分:1)

从Spark 2.4.0开始,就有Dataset.isEmpty

它的implementation是:

  try{  //wrap around possible cause of error or notice

    if(!empty($_POST['G'])){
        echo $_POST['C'];
    }

  }catch(Exception $e){

    //handle the error message $e->getMessage();
  }

请注意,def isEmpty: Boolean = withAction("isEmpty", limit(1).groupBy().count().queryExecution) { plan => plan.executeCollect().head.getLong(0) == 0 } 不再是Scala中的类,而只是type alias(可能在Spark 2.0中已更改):

DataFrame

答案 9 :(得分:0)

df1.take(1).length>0

take方法返回行数组,因此如果数组大小等于零,则df中没有记录。

答案 10 :(得分:0)

我发现在某些情况下:

>>>print(type(df))
<class 'pyspark.sql.dataframe.DataFrame'>

>>>df.take(1).isEmpty
'list' object has no attribute 'isEmpty'

这与“length”相同或者用head()替换take()

[解决方案]我们可以使用的问题。

>>>df.limit(2).count() > 1
False

答案 11 :(得分:0)

在PySpark上,您也可以使用此bool(df.head(1))获得True值的False

如果数据框不包含任何行,则返回False

答案 12 :(得分:0)

假设我们有以下空数据框:

df = spark.sql("show tables").limit(0)

如果您使用的是 Spark 2.1,对于 pyspark,要检查此数据框是否为空,您可以使用:

df.count() > 0

bool(df.head(1))

答案 13 :(得分:0)

用于 DataFrames 的 isEmpty() 方法是在 Spark 2.4 版中引入的。因此,在任何版本的 spark 2.4 或更高版本上检查 DataFrame 是否为空的最佳方法是使用函数 isEmpty()

df.isEmpty()

答案 14 :(得分:-1)

dataframe.limit(1).count > 0

这也触发了一项工作,但是由于我们选择的是单条记录,即使是数十亿条记录,时间消耗也可能更低。

发件人: https://medium.com/checking-emptiness-in-distributed-objects/count-vs-isempty-surprised-to-see-the-impact-fa70c0246ee0

答案 15 :(得分:-2)

你可以这样做:

val df = sqlContext.emptyDataFrame
if( df.eq(sqlContext.emptyDataFrame) )
    println("empty df ")
else 
    println("normal df")