Сегодня расскажем, как работать с файлами формата JSON в PySpark. В этой статье вы узнаете: как прочитать файл JSON, каким должен быть формат, чтобы PySpark прочитал его корректно, и как записать файл JSON.
Что такое JSON
JSON (JavaScript Object Notation) — это формат для хранения данных. Несмотря на свое название, он применяется не только в проектах с JavaScript. Есть даже СУБД, например, MongoDB, основной формат, которых это JSON.
Основное преимущество этого формата — читаемость. Причем люди, работающие с Python, не найдут его сложным (в отличие от XML, например).
Составные объекты помещаются в фигурные скобки, массивы в квадратные, атрибуты и строки в двойные кавычки. Также имеется специальный символ — null
, обозначающий нулевое значение объекта. Пример JSON, представляющий человека:
{ "firstName": "John", "isAlive": true, "age": 27, "address": { "streetAddress": "21 2nd Street", "city": "New York", }, "phoneNumbers": [ { "type": "home", "number": "212 555-1234" }, { "type": "office", "number": "646 555-4567" } ], "children": ["Alex", "Anna"], "spouse": null }
Очень важным моментом является отсутствие запятой у самого последнего атрибута. В Python в некоторых случаях разрешено оставлять, здесь же — нет.
Читаем JSON файлы в DataFrame
Во-первых, следует знать, что, в отличие от чтения CSV, по умолчанию чтение JSON применяет определение типов (inferschema
); это значит, что если файл большой, то читаться он будет не быстро.
Код курса
GRAS
Ближайшая дата курса
по запросу
Продолжительность
ак.часов
Стоимость обучения
0 руб.
Во-вторых, по умолчанию однострочное чтение. Это значит, что каждый объект, которая в итоге должна быть интерпретирована как строка DataFrame, должен находиться на одной строке. Поэтому пример выше он не прочитает, если не дать дополнительные аргументы.
Например, есть JSON-файл:
{ "name": "John", "age": 27 }, { "name": "Alex", "age": 32 }, { "name": "Anna", "age": null }
Тогда его чтение осуществляется очень просто:
df = spark.read.json("data.json") df.show() """ +----+----+ | age|name| +----+----+ | 27|John| | 32|Alex| |null|Anna| +----+----+ """
Чтение многострочных JSON-файлов
Если же объект задан в многострочном виде, например, так (или просто объекты в виде списка):
[{ "name": "John", "age": 27 }, { "name": "Alex", "age": 32 }, { "name": "Anna", "age": null }]
Тогда прочитать его можно следующим образом:
spark.read.json("data.json", multiLine=True)
Либо так:
df = spark.read.option("multiline", "true").json("data.json")
Обратите внимание на то, что объекты заключены в квадратные скобки. Иначе, PySpark прочитал бы JSON неправильно. С другой стороны, если у вас однострочники и они не определены как массив, т.е. не заключены в квадратные скобки, то при значение multiLine=True
, файл также будет прочитан неправильно. Поэтому будьте осторожны.
Чтение нескольких JSON-файлов одновременно
Чтобы прочитать несколько файлов, передайте их пути в виде списка:
df = spark.read.json(["data.json", "data2.json"], multiLine=True) df.show() """ +----+----+ | age|name| +----+----+ | 27|John| | 32|Alex| |null|Anna| | 77|Mila| | 33|Gowl| | 15|Bona| +----+----+ """
Можно использовать групповые символы, например:
df = spark.read.json("/full/path/*.json")
Как уже было сказано, неправильное чтение может произойти, если в одном файле однострочнике, а в другом нет. Тогда вы можете прочитать их по отдельности, а затем соединить друг с другом (об этом мы рассказывали в статье):
df1 = spark.read.json("data.json", multiLine=True) df2 = spark.read.json("data2.json") df = df1.union(df2)
Чтение с заданной схемой
Чтобы ускорить процесс чтения, можно не использовать inferSchema
. Для этого нужно определить структуру таблицы (схема). Например, в нашем случае имеется два поля, тогда схема будет иметь вид:
from pyspark.sql.types import StructField, IntegerType, StringType schema = StructType([ StructField("name", StringType()), StructField("age", IntegerType()) ]) df = spark.read.json("data.json", schema, multiLine=True).show()
Однако это работает только с заранее известной схемой.
Запись в JSON в PySpark
Для записи используйте метод write.json
, который создает директорию, в которую записывает в виде партиций сам файл. В качестве опционального параметра (mode
) можно дать:
append
добавить в конец существующего файла;overwrite
перезаписать файл, тогда старые данные будут утеряны;ignore
не записывать в файл, если файл уже существует;error
выдать ошибку, если файл уже существует (используется по умолчанию).
# Будет создана директория, в которой будет лежать файл df.write.json("new", mode="append")
В следующей статье познакомимся с функциями для работы с JSON-файлами. О том, как работать с JSON и другими форматами в PySpark вы узнаете на наших образовательных курсах в лицензированном учебном центре обучения и повышения квалификации руководителей и ИТ-специалистов (менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data) в Москве:
- Анализ данных с Apache Spark
- Машинное обучение в Apache Spark
- Графовые алгоритмы в Apache Spark
- Потоковая обработка в Apache Spark
- Основы Apache Spark для разработчиков