Питоновский эквивалент запроса Wolfram Language для JSON?

Вопрос или проблема

Язык Wolfram имеет функцию Query, которая может обходить структуры данных и применять функции на разных уровнях структуры. Я работаю со структурами JSON многомерного уровня и мне нужна функция, которая имеет аналогичную функциональность функции Query в языке Wolfram.

Какой пакет Python и функции лучше всего воспроизводят это?

Для минимально работающего примера предположим, что у меня есть следующая структура JSON. (Экранирование строк опущено для простоты)

x = {
    "Dims1":[
        {
            "Apple":{
                "Baking":[
                    "Pie",
                    "Tart"
                ],
                "Plant":"Tree",
                "Tons":{
                    "2017":1.23e1,
                    "2018":1.12e1
                }
            }
        },
        {
            "Tomato":{
                "Cooking":[
                    "Stew",
                    "Sauce"
                ],
                "Plant":"Vine",
                "Tons":{
                    "2017":8.1,
                    "2018":8.3
                }
            }
        },
        {
            "Banana":{
                "Name":"Banana",
                "Baking":[
                    "Bread"
                ],
                "Cooking":[
                    "Fried"
                ],
                "Plant":"Arborescent",
                "Tons":{
                    "2017":0.8,
                    "2018":0.5
                }
            }
        }
    ],
    "Dims2":[
        {
            "Apple":{
                "Name":"Apple",
                "Baking":[
                    "Pie",
                    "Tart"
                ],
                "Plant":"Tree",
                "Tons":{
                    "2017":1.31e1,
                    "2018":1.01e1
                }
            }
        },
        {
            "Sweet Potato":{
                "Cooking":[
                    "Fried",
                    "Steamed"
                ],
                "Baking":[
                    "Pie"
                ],
                "Plant":"Vine",
                "Tons":{
                    "2017":1.11e1,
                    "2018":1.91e1
                }
            }
        }
    ]
}

В языке Wolfram я могу

a = GeneralUtilities`ToAssociations@ImportString[x, "JSON"]
<|
 "Dims1" ->
  {
   <|"Apple" ->
     <|"Baking" -> {"Pie", "Tart"}, "Plant" -> "Tree",
      "Tons" -> <|"2017" -> 12.3, "2018" -> 11.2|>|>
    |>,
   <|"Tomato" -> 
     <|"Cooking" -> {"Stew", "Sauce"}, "Plant" -> "Vine",
      "Tons" -> <|"2017" -> 8.1, "2018" -> 8.3|>|>
    |>,
   <|"Banana" ->
     <|"Name" -> "Banana", "Baking" -> {"Bread"}, 
      "Cooking" -> {"Fried"}, "Plant" -> "Arborescent",
      "Tons" -> <|"2017" -> 0.8, "2018" -> 0.5|>|>
    |>
   },
 "Dims2" ->
  {
   <|"Apple" ->
     <|"Name" -> "Apple", "Baking" -> {"Pie", "Tart"}, 
      "Plant" -> "Tree",
      "Tons" -> <|"2017" -> 13.1, "2018" -> 10.1|>|>
    |>,
   <|"Sweet Potato" ->
     <|"Cooking" -> {"Fried", "Steamed"}, "Baking" -> {"Pie"}, 
      "Plant" -> "Vine",
      "Tons" -> <|"2017" -> 11.1, "2018" -> 19.1|>|>
    |>
   }
 |>

и затем с помощью Query

Query[All, All, All, {"Baking"}]@a
<|"Dims1" -> 
   {<|"Apple" -> <|"Baking" -> {"Pie", "Tart"}|>|>, 
    <|"Tomato" -> <|"Baking" -> Missing["KeyAbsent", "Baking"]|>|>, 
    <|"Banana" -> <|"Baking" -> {"Bread"}|>|>}, 
  "Dims2" -> 
   {<|"Apple" -> <|"Baking" -> {"Pie", "Tart"}|>|>, 
    <|"Sweet Potato" -> <|"Baking" -> {"Pie"}|>|>}
|>

и включать функции такие как

Query[All, Join /* Flatten /* DeleteDuplicates, Values, "Baking" /* DeleteMissing]@a
<|"Dims1" -> {"Pie", "Tart", "Bread"}, "Dims2" -> {"Pie", "Tart"}|>

и

Query[All, Merge[Total] /* DateListPlot, All, "Tons", 
  KeyMap[DateObject[{FromDigits@#}, "Year"] &]]@a

введите описание изображения здесь

Как это сделать с JSON в Python?

ObjectPath — это язык запросов для полуструктурированных данных, включая JSON, и имеет API для Python.

Ответ или решение

Для решения задачи извлечения данных из многослойных JSON-структур в Python можно использовать несколько подходов, аналогичных функционалу Wolfram Language Query. Наиболее подходящими инструментами для этих целей являются библиотеки, такие как pandas, jsonpath-ng и ObjectPath. В этой статье мы рассмотрим, как использовать эти библиотеки для выполнения запросов, эквивалентных Wolfram Language, и проиллюстрируем это на примере указанной структуры JSON.

Пример структуры JSON

Для начала, давайте определим JSON-объект, с которым будем работать:

x = {
    "Dims1": [
        {
            "Apple": {
                "Baking": ["Pie", "Tart"],
                "Plant": "Tree",
                "Tons": {
                    "2017": 12.3,
                    "2018": 11.2
                }
            }
        },
        {
            "Tomato": {
                "Cooking": ["Stew", "Sauce"],
                "Plant": "Vine",
                "Tons": {
                    "2017": 8.1,
                    "2018": 8.3
                }
            }
        },
        {
            "Banana": {
                "Name": "Banana",
                "Baking": ["Bread"],
                "Cooking": ["Fried"],
                "Plant": "Arborescent",
                "Tons": {
                    "2017": 0.8,
                    "2018": 0.5
                }
            }
        }
    ],
    "Dims2": [
        {
            "Apple": {
                "Name": "Apple",
                "Baking": ["Pie", "Tart"],
                "Plant": "Tree",
                "Tons": {
                    "2017": 13.1,
                    "2018": 10.1
                }
            }
        },
        {
            "Sweet Potato": {
                "Cooking": ["Fried", "Steamed"],
                "Baking": ["Pie"],
                "Plant": "Vine",
                "Tons": {
                    "2017": 11.1,
                    "2018": 19.1
                }
            }
        }
    ]
}

Использование pandas

Библиотека pandas предоставляет мощные средства для обработки данных и позволяет проводить выборки из сложных структур. Для извлечения данных из вышеуказанного JSON можно воспользоваться следующими шагами:

  1. Установите библиотеку pandas, если она еще не установлена:
pip install pandas
  1. Преобразуйте JSON в DataFrame и выполните выборку:
import pandas as pd

# Преобразование JSON в DataFrame
df_dims1 = pd.json_normalize(x['Dims1'])
df_dims2 = pd.json_normalize(x['Dims2'])

# Объединение и выполнение выборки
combined_df = pd.concat([df_dims1, df_dims2], keys=['Dims1', 'Dims2'])

# Извлечение данных по ключу "Baking"
baking_items = combined_df.apply(lambda row: row['Apple'].get('Baking', None), axis=1).dropna()
print(baking_items)

Использование jsonpath-ng

jsonpath-ng — это библиотека для выполнения запросов к JSON-структуре по подобию XPath для XML. Чтобы использовать эту библиотеку, выполните следующие шаги:

  1. Установите jsonpath-ng:
pip install jsonpath-ng
  1. Используйте jsonpath для извлечения данных:
from jsonpath_ng import jsonpath, parse

jsonpath_expr = parse('$.Dims1[*].Apple.Baking')
baking_items = [match.value for match in jsonpath_expr.find(x)]
print(baking_items)

Использование ObjectPath

ObjectPath — это еще одна библиотека для работы с полуструктурированными данными, такой как JSON, с интересным и простым синтаксисом для запросов.

  1. Установите ObjectPath:
pip install objectpath
  1. Выполните запрос:
import objectpath

# Создание базы данных на основе JSON
generator = objectpath.ObjectPath(x)

# Выполнение запроса к БД
baking_items = generator.execute('$..Baking')
print(baking_items)

Заключение

Вышеописанные подходы предоставляют гибкие возможности для работы с многослойными JSON-структурами в Python. Каждая библиотека предлагает уникальные функции, и выбор зависит от ваших предпочтений и задач. Библиотека pandas отлично подходит для обработки табличных данных, в то время как jsonpath-ng и ObjectPath позволяют более интуитивно работать с вложенными структурами. Определите наиболее подходящий вариант для вашей задачи, исследуя функционал каждой библиотеки.

Оцените материал
Добавить комментарий

Капча загружается...