现在,我必须使用df.count > 0
检查DataFrame
是否为空。但它效率低下。有没有更好的方法呢。
感谢。
PS:我想检查它是否为空,以便我只保存DataFrame
如果它不是空的
答案 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.NoSuchElementException
。 first()
直接调用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)
完成而不是空行时,数据帧会返回错误。我突出显示了它抛出错误的特定代码行。
答案 4 :(得分:4)
我有相同的问题,并且测试了3个主要解决方案:
当然这3种都可以工作,但是就性能而言,这是我在机器上同一DF上执行这些方法时发现的结果,即执行时间:
因此,我认为最好的解决方案是 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
这也触发了一项工作,但是由于我们选择的是单条记录,即使是数十亿条记录,时间消耗也可能更低。
答案 15 :(得分:-2)
你可以这样做:
val df = sqlContext.emptyDataFrame
if( df.eq(sqlContext.emptyDataFrame) )
println("empty df ")
else
println("normal df")