Подтвердить что ты не робот

Как проверить, что искровой датафрейм пуст?

Прямо сейчас я должен использовать df.count > 0, чтобы проверить, пустой ли DataFrame или нет. Но это неэффективно. Есть ли лучший способ сделать это?

Благодаря.

PS: я хочу проверить, если он пустой, так что я могу сохранить DataFrame только если он не пустой

4b9b3361

Ответ 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")