回答:
スパーク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))
とを使用するdf.first()と、DataFrameが空の場合にdf.head()両方が返されjava.util.NoSuchElementExceptionます。first()がhead()直接呼び出され、が呼び出されますhead(1).head。
def first(): T = head()
def head(): T = head(1).head
head(1)は配列を返すためhead、その配列をjava.util.NoSuchElementException取得すると、DataFrameが空のときにが発生します。
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)、以下が、少なくとも私が言うことができるものから、全て等価であり、あなたがキャッチする必要はありませんので、方法)java.util.NoSuchElementExceptionデータフレームが空の場合に例外を。
df.head(1).isEmpty
df.take(1).isEmpty
df.limit(1).collect().isEmpty
私はこれが古い質問であることを知っているので、うまくいけば、新しいバージョンのSparkを使用している人に役立つでしょう。
df.rdd.isEmptyですか?
df.head(1)、時間がかかっている場合は、おそらく、dfsの実行計画が、sparkがショートカットを取得できないような複雑な処理を行っていることが原因です。たとえば、単に寄木細工のファイルから読み取る場合df = spark.read.parquet(...)、sparkは1つのファイルパーティションのみを読み取ると確信しています。しかし、df集計などの他のことをしている場合は、誤って、sparkにソースデータのすべてではないにしても、大部分を読み取って処理させる可能性があります。
df.limit(1).count()です。大きなデータセットでは、ほぼ瞬時に報告される@ hulin003によって報告された例よりもはるかに時間がかかります
根底にあるものをつかむだけRDDです。Scalaの場合:
df.rdd.isEmpty
Pythonの場合:
df.rdd.isEmpty()
そうは言っても、これはcall take(1).lengthだけなので、Rohanが答えたのと同じことをします...もう少し明示的でしょうか?
あなたはの利点を取ることができますhead()(またはfirst()かどうかを確認するために)関数DataFrame単一の行を持っています。もしそうなら、それは空ではありません。
Spark 2.4.0以降にありDataset.isEmptyます。
それの実装は:
def isEmpty: Boolean =
withAction("isEmpty", limit(1).groupBy().count().queryExecution) { plan =>
plan.executeCollect().head.getLong(0) == 0
}
a DataFrameはもはやScalaのクラスではなく、単なる型のエイリアス(おそらくSpark 2.0で変更された)であることに注意してください。
type DataFrame = Dataset[Row]
Javaユーザーの場合、これをデータセットで使用できます。
public boolean isDatasetEmpty(Dataset<Row> ds) {
boolean isEmpty;
try {
isEmpty = ((Row[]) ds.head(1)).length == 0;
} catch (Exception e) {
return true;
}
return isEmpty;
}
これにより、考えられるすべてのシナリオがチェックされます(empty、null)。
する場合df.count > 0。すべてのエグゼキューター全体のすべてのパーティションの数を取得し、それらをドライバーで合計します。何百万もの行を処理する場合、これにはしばらく時間がかかります。
これを行う最良の方法はdf.take(1)、そのnull を実行して確認することです。これはjava.util.NoSuchElementException試してみるのにとても良いでしょうdf.take(1)。
take(1)空の行の代わりにデータフレームが完了すると、エラーが返されます。エラーをスローする特定のコード行を強調表示しました。
count方法には時間がかかります。
Scalaでは、暗黙を使用してメソッドとDataFrame API を追加できます。これにより、コードが読みやすくなります。isEmpty()nonEmpty()
object DataFrameExtensions {
implicit def extendedDataFrame(dataFrame: DataFrame): ExtendedDataFrame =
new ExtendedDataFrame(dataFrame: DataFrame)
class ExtendedDataFrame(dataFrame: DataFrame) {
def isEmpty(): Boolean = dataFrame.head(1).isEmpty // Any implementation can be used
def nonEmpty(): Boolean = !isEmpty
}
}
ここでは、他のメソッドも追加できます。暗黙的な変換を使用するimport DataFrameExtensions._には、拡張機能を使用するファイルでを使用します。その後、メソッドはそのまま次のように使用できます。
val df: DataFrame = ...
if (df.isEmpty) {
// Do something
}
同じ質問があり、3つの主な解決策をテストしました:
そしてもちろん3つは動作しますが、パフォーマンスに関しては、実行時間に関して、マシンの同じDFでこれらのメソッドを実行したときに次のことがわかりました。
したがって、@ Justin Pihonyが示唆するように、最善の解決策はdf.rdd.isEmptyだと思います
私はいくつかのケースでそれを発見しました:
>>>print(type(df))
<class 'pyspark.sql.dataframe.DataFrame'>
>>>df.take(1).isEmpty
'list' object has no attribute 'isEmpty'
これは「長さ」と同じか、take()をhead()に置き換えます
【解決方法】使用できる問題について。
>>>df.limit(2).count() > 1
False
dataframe.limit(1).count > 0
これもジョブをトリガーしますが、1つのレコードを選択しているため、10億規模のレコードの場合でも、時間の消費ははるかに少なくなる可能性があります。
送信元:https : //medium.com/checking-emptiness-in-distributed-objects/count-vs-isempty-surprised-to-see-the-impact-fa70c0246ee0
あなたはそれを次のように行うことができます:
val df = sqlContext.emptyDataFrame
if( df.eq(sqlContext.emptyDataFrame) )
println("empty df ")
else
println("normal df")
schema、2つのデータフレーム(sqlContext.emptyDataFrame&df)が同じである必要はありませんtrueか?
eqから継承され、引数(that)がレシーバーオブジェクト(this)への参照であるかどうかAnyRefをテストします。