Проверьте, пуст ли фрейм данных pyspark, что вызывает проблемы с памятью

У меня есть таблица, в которой около 1 миллиарда записей. Я запускаю запрос, чтобы найти дубликаты. Если результатом запроса является 0 строк, дубликатов нет, иначе есть. Если есть дубликаты, я хочу записать это имя таблицы в текстовый файл. Так что я делаю

df = spark.sql("SELECT count(*) FROM table GROUP BY key1,key2,key3 HAVING count(*) > 1 LIMIT 1)
if df.count() > 0:
    with open('duplicate_tables.txt','a') as file:
        file.write('\n' + table)

На df.count() строка, я получаю сообщение об ошибке java.io.IOException: No space left on device. Это потому чтоcount()неэффективно. Я также получаю ту же ошибку, когда пытаюсь использовать

if len(df.head(1)) != 0:

В своем запросе я подумал (надеялся), что добавление LIMIT 1 поможет, чтобы ему не пришлось проходить сотни и сотни строк, просто проверьте, пуст он или нет. Если я вынимаю счетную часть, все работает нормально.

Я видел несколько способов переписать оператор count (я прошел через Как проверить, пуст ли фрейм данных искры?), Но пока мне не повезло.

2 ответа

Спарк ленивый. Это означает, что когда вы бежитеspark.sql()на самом деле ничего не происходит. Вы можете убедиться в этом, заметив, чтоspark.sql()"выполняется" немедленно, независимо от сложности SQL. Фактическая обработка выполняется после того, как требуется действие; в вашем случае, когда.count()вступает в игру. Последнее, вероятно, вызывает проблему с памятью из-за сложности SQL и размера таблицы.

Возможно, вы могли бы попробовать еще одну вещь - прочитать всю таблицу и запустить Spark для проверки наличия дубликатов. Однако, учитывая исходный размер вашей таблицы, это также может привести к проблемам с памятью.

df = spark.sql("SELECT * FROM table") # or select particular column(s)
if df.count() != df.dropDuplicates().count():
    with open('duplicate_tables.txt','a') as file:
        file.write('\n' + table)

Я обнаружил, что это более эффективный способ определить, действительно ли фрейм данных искры пуст:

df.first() == Нет

после тестирования с помощью .limit(1), .head(), .count () и т. д.

Другие вопросы по тегам