Как проверить, что искровой датафрейм пуст?
Прямо сейчас я должен использовать df.count > 0
, чтобы проверить, пустой ли DataFrame
или нет. Но это неэффективно. Есть ли лучший способ сделать это?
Благодаря.
PS: я хочу проверить, если он пустой, так что я могу сохранить DataFrame
только если он не пустой
Ответы
Ответ 1
Для 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))
Использование df.first()
и df.head()
вернет java.util.NoSuchElementException
если DataFrame пуст. first()
вызывает head()
напрямую, что вызывает head(1).head
.
def first(): T = head()
def head(): T = head(1).head
head(1)
возвращает Array, поэтому, взяв head
на этот Array, возникает исключение 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
в limit(n).queryExecution
head(n: Int)
), поэтому все следующее эквивалентно, по крайней мере из того, что я могу сказать, и вам не придется перехватывать исключение java.util.NoSuchElementException
когда DataFrame пуст.
df.head(1).isEmpty
df.take(1).isEmpty
df.limit(1).collect().isEmpty
Я знаю, что это старый вопрос, поэтому, надеюсь, он поможет кому-то использовать более новую версию Spark.
Ответ 2
Я бы сказал, чтобы просто захватить основной RDD
. В Scala:
df.rdd.isEmpty
в Python:
df.rdd.isEmpty()
При этом все, что он делает, это вызывает take(1).length
, так что он будет делать то же самое, что ответил Рохан... просто, может быть, чуть более явно?
Ответ 3
Вы можете воспользоваться функциями head()
(или first()
), чтобы увидеть, имеет ли DataFrame
одну строку. Если это так, это не пусто.
Ответ 4
Если вы делаете df.count > 0
. Он берет подсчет всех разделов всех исполнителей и добавляет их в Driver. Это займет некоторое время, когда вы имеете дело с миллионами строк.
Лучший способ сделать это - выполнить df.take(1)
и проверить, имеет ли оно значение null. Это вернет java.util.NoSuchElementException
поэтому лучше попытаться использовать df.take(1)
.
Фрейм данных возвращает ошибку при выполнении take(1)
вместо пустой строки. Я выделил конкретные строки кода, где он выдает ошибку.
![enter image description here]()
Ответ 5
Для пользователей 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
Начиная с Spark 2.4.0 есть Dataset.isEmpty
.
Это реализация:
def isEmpty: Boolean =
withAction("isEmpty", limit(1).groupBy().count().queryExecution) { plan =>
plan.executeCollect().head.getLong(0) == 0
}
Обратите внимание, что DataFrame
больше не является классом в Scala, это просто псевдоним типа (вероятно, измененный в Spark 2.0):
type DataFrame = Dataset[Row]
Ответ 7
В Scala вы можете использовать импликации для добавления методов isEmpty()
и nonEmpty()
к API DataFrame, что сделает код более приятным для чтения.
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
}
Ответ 8
Если вы используете Pypsark, вы также можете сделать:
len(df.head(1)) > 0
Ответ 9
df1.take(1).length>0
Метод take
возвращает массив строк, поэтому, если размер массива равен нулю, в df
нет записей.
Ответ 10
Я обнаружил, что в некоторых случаях:
>>>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
Ответ 11
Я думаю, что производительность каждой из команд, показанных выше, все еще будет зависеть от того, было ли какое-либо действие фактически выполнено над набором данных или оно только что было преобразовано до сих пор. см. ленивую оценку (https://data-flair.training/blogs/apache-spark-lazy-evaluation/). Если ваш фрейм данных еще не был оценен, то независимо от того, используете ли вы count() или head (1), время может не сильно отличаться, то же самое относится и к limit().
Ответ 12
В PySpark вы также можете использовать этот bool(df.head(1))
для получения значения True
of False
Возвращает False
если в фрейме данных нет строк
Ответ 13
Вы можете сделать это как:
val df = sqlContext.emptyDataFrame
if( df.eq(sqlContext.emptyDataFrame) )
println("empty df ")
else
println("normal df")