Как использовать miller mlr или jq, чтобы объединить два массива JSON в один массив?

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

Ранее я был мазохистом jq, но открыл для себя mlr, который, похоже, предлагает возможность большего (но другого) страдания.

Я нашел хороший веб-сайт, который позволяет мне отправлять команды curl без ключей API и т.д., чтобы получить данные, которые меня интересуют. Проблема в том, что выбранный мной инструмент для отображения данных (Datagraph от Visual Data Tools) не может разобрать выданный JSON.

Я мог бы написать что-то неаккуратное, используя awk, sed и т.д., но было бы более элегантно использовать что-то вроде jq или mlr, чтобы достигнуть этого в одну строку.

Пары (x, y) находятся в отдельных массивах. Есть ли однострочная команда, которая достичь следующего?

Укороченный пример данных, которые мне нужно преобразовать. Похоже, я мог бы преобразовать JSON в JSON, или JSON в CSV, чтобы достичь своей цели.

{
    "btcusd": {
        "x": [
            1254700800000,
            1254787200000,
            1254873600000,
            1730419200000
        ],
        "y": [
            0.00076394,
            0.00076394,
            0.00088456,
            69513.1578978095
        ]
    },
    "xaubtc": {
        "x": [
            1254700800000,
            1254787200000,
            1254873600000,
            1719446400000
        ],
        "y": [
            1316202.8431552218,
            1359727.2037070976,
            1176008.410961382,
            0.037321851310868535
        ]
    }
}

Пример выходных данных, которые может разобрать Datagraph (создан вручную):

[
   {
      "pair" : "btcusd",
      "x" : 1254700800000,
      "y" : 0.00076394
   },
   {
      "pair" : "btcusd",
      "x" : 1254787200000,
      "y" : 0.00076394
   },
   {
      "pair" : "btcusd",
      "x" : 1254873600000,
      "y" : 0.00088456
   },
   {
      "pair" : "btcusd",
      "x" : 1730419200000,
      "y" : 69513.1578978095
   },
   {
      "pair" : "xaubtc",
      "x" : 1254700800000,
      "y" : 1316202.84315522
   },
   {
      "pair" : "xaubtc",
      "x" : 1254787200000,
      "y" : 1359727.2037071
   },
   {
      "pair" : "xaubtc",
      "x" : 1254873600000,
      "y" : 1176008.41096138
   },
   {
      "pair" : "xaubtc",
      "x" : 1719446400000,
      "y" : 0.0373218513108685
   }
]

Что приводит к такого рода таблице в Datagraph

pair    y                   x
btcusd  0.00076394          1.2547008e12
btcusd  0.00076394          1.2547872e12
btcusd  0.00088456          1.2548736e12
btcusd  69513.1578978095    1.7304192e12
xaubtc  1.31620284315522e6  1.2547008e12
xaubtc  1.3597272037071e6   1.2547872e12
xaubtc  1.17600841096138e6  1.2548736e12
xaubtc  0.0373218513108686  1.7194464e12

Хотя это было бы лучше (вручную красиво напечатано)

pair1   x1             y1                pair2   x2             y2
btcusd  1254700800000  0.00076394        xaubtc  1254700800000  1316202.8431552218
btcusd  1254787200000  0.00076394        xaubtc  1254787200000  1359727.2037070976
btcusd  1254873600000  0.00088456        xaubtc  1254873600000  1176008.410961382
btcusd  1730419200000  69513.1578978095  xaubtc  1719446400000  0.037321851310868535

Вам нужно что-то вроде этого:

to_entries | map({pair: .key} + (.value | transpose[] | {x: .[0], y: .[1]}))

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

Для объединения двух JSON-массивов в один массив, вы можете использовать инструменты jq или mlr. Ниже приведены примеры, основанные на предоставленных вами данных и требуемом выходном формате.

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

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

jq '[to_entries | .[] | .value.x | to_entries | map({pair: .key, x: .value, y: (.[].y)}) | .] | add' input.json

Объяснение запроса

  1. to_entries — преобразует объект в массив объектов, где каждый элемент содержит ключ и значение.
  2. .[] — перебирает все элементы массива, извлекая значения.
  3. .value.x — выбирает массив x у каждой валютной пары.
  4. to_entries — снова преобразуем массив для дальнейшей обработки.
  5. map({pair: .key, x: .value, y: (.[].y)}) — создает новый массив объектов, где каждый объект содержит пару, значение x и соответствующее значение y.
  6. add — объединяет все элементы в один массив.

Пример использования

Для запуска команды вы можете сохранить ваши данные в файл input.json, а затем выполнить команду в терминале. Результат будет выглядеть так, как вы ожидаете, с нужными вам парами данных.

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

mlr (Miller) также предлагает эффективные средства для обработки и трансформации данных. Вы можете использовать следующую команду:

mlr --j2c unsparsify then \
    put '$pair = $btcusd.x' then \
    reshape -r 2 -p $x, $y \
    then \
    filter '$pair' then \
    put '$pair = "btcusd"' input.json

Объяснение запроса

  1. –j2c — указывает mlr на использование формата JSON.
  2. unsparsify — преобразует данные в плоскую структуру.
  3. put ‘$pair = $btcusd.x’ — добавляет поле pair в каждый объект данных.
  4. reshape -r 2 -p $x, $y — форматирует ключи массива.
  5. filter ‘$pair’ — фильтрует данные по значению pair.
  6. put ‘$pair = "btcusd"’ — добавляет нужное значение пары.

Запустив указанные выше команды, вы получите объединенные значения из массива x и массива y в одном выходном массиве, который можно будет использовать для дальнейшей обработки в вашем инструменте визуализации данных.

Заключение

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

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

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