Пошаговое руководство по использованию Spark для выполнения исследовательского анализа данных для наборов данных, размер которых превышает объем памяти.

Анализ наборов данных, размер которых превышает доступную оперативную память, с помощью записных книжек Jupyter и фреймов данных Pandas является сложной задачей. Эта проблема уже решалась (например, здесь или здесь), но моя цель здесь немного другая. Я представлю метод выполнения исследовательского анализа большого набора данных с целью выявления и фильтрации ненужных данных. Надеемся, что в конце отфильтрованный набор данных сможет обработать Pandas для остальных вычислений.

Идея этой статьи возникла в одном из моих последних проектов, связанных с анализом базы данных Open Food Facts. Он содержит информацию о пищевой ценности продуктов, продаваемых по всему миру, и на момент написания статьи экспорт csv, который они предоставляют, составлял 4,2 ГБ. Это было больше, чем 3 ГБ оперативной памяти, которые у меня были на моей виртуальной машине Ubuntu. Однако с помощью PySpark я смог провести некоторый анализ и выбрать только интересующую информацию из моего проекта.

Чтобы настроить среду Ubuntu, я сделал следующие шаги:

  1. Установить Anaconda
  2. Установите Java openJDK 11: sudo apt-get install openjdk-11-jdk. Версия Java важна, поскольку Spark работает только с Java 8 или 11.
  3. Установите Apache Spark (версия 3.1.2 для Hadoop 2.7 здесь) и настройте среду Spark (добавьте переменную SPARK_HOME в PATH). Если все прошло хорошо, вы сможете запустить Spark-Shell в своем терминале.
  4. Установите pyspark: conda install -c conda-forge pyspark

Я начал с импорта модуля pyspark.sql и создания локального SparkSession:

Я прочитал данные из моего большого файла csv, используя переменную sc SparkSession. Попытка загрузить файл размером 4,2 ГБ на виртуальную машину с объемом оперативной памяти всего 3 ГБ не вызывает ошибок, поскольку Spark фактически не пытается прочитать данные, если не требуется какой-либо тип вычислений.

Результатом является переменная pyspark.sql.dataframe. Важно помнить, что на этом этапе данные фактически не загружаются в оперативную память. Данные загружаются только тогда, когда для переменной pyspark вызывается действие, которое должно возвращать вычисленное значение. Если я попрошу, например, подсчитать количество продуктов в наборе данных, Spark достаточно умен, чтобы не пытаться загрузить все 4,2 ГБ данных, чтобы вычислить это значение (почти 2 миллиона продуктов).

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

Чтобы начать поисковый анализ, я вычислил количество продуктов в каждой стране, чтобы получить представление о составе базы данных:

BDD_countries также является фреймом данных pyspark и имеет следующую структуру:

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

Отсюда я могу, например, отфильтровать все продукты, недоступные во Франции, и выполнить остальную часть анализа на меньшем, более простом для обработки наборе данных.

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