Частичное вертикальное кэширование DataFrame

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

myDataFrame.select("field1").cache
myDataFrame.select("field1").count
myDataFrame.select("field1").where($"field1">5).count
myDataFrame.select("field1", "field2").where($"field1">5).count

Четвертая строка не использует кеш.

Какие-нибудь простые решения, которые могут помочь здесь?

1 ответ

Причина, по которой это не будет кешироваться, состоит в том, что всякий раз, когда вы выполняете преобразование на фрейме данных (например, выберите), вы фактически создаете новый. Что вы в основном сделали, так это кэшировали фрейм данных, содержащий только field1, и фрейм данных, содержащий только field1, где оно больше 5 (возможно, вы имели в виду field2 здесь, но это не имеет значения).

В четвертой строке вы создаете третий фрейм данных, который не имеет родословной для исходных двух, только для исходного фрейма данных.

Если вы обычно делаете сильную фильтрацию (т.е. получаете очень небольшое количество элементов), вы можете сделать что-то вроде этого:

cachedDF = myDataFrame.select("field1", "field2", ... "fieldn").cache
cachedDF.count()
filteredDF = cachedDF.filter(some strong filter)
res = myDataFrame.join(broadcast(filteredDF), cond)

то есть cachedDF имеет все поля, по которым вы фильтруете, затем вы фильтруете очень сильно, а затем выполняете внутреннее соединение (с cond, являющимся всеми релевантными выбранными полями или некоторым полем id), которое даст все соответствующие данные.

Тем не менее, в большинстве случаев, при условии, что вы используете такой формат файла, как паркет, кэширование вам мало чем поможет.

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