изменить JQ вложенный файл и сделать CSV - PullRequest
0 голосов
/ 28 февраля 2019

Я боролся с этим весь день, который я хочу превратить в CSV.

Представляет офицеров, прикрепленных к компании, чей номер "OC418979" в API британской компании компании.

Я уже обрезал json, чтобы он содержал только 2 объекта внутри "элементов".

Я хотел бы получить CSV, подобный этому

OC418979, country_of_residence, officer_role, appointed_on
OC418979, country_of_residence, officer_role, appointed_on
OC418979, country_of_residence, officer_role, appointed_on
OC418979, country_of_residence, officer_role, appointed_on
...

Есть 2 дополнительных сложности: есть 2 типа «офицеров», некоторые люди, некоторые компании, поэтомуне все ключи в людях присутствуют в другом и наоборот.Я хотел бы, чтобы эти записи были нулевыми.Второе усложнение - это те вложенные объекты, как «имя», в котором есть запятая!или адрес, который содержит несколько подобъектов (которые, я думаю, я мог бы сгладить в pandas tho).

{
  "total_results": 13,
  "resigned_count": 9,
  "links": {
    "self": "/company/OC418979/officers"
  },
  "items_per_page": 35,
  "etag": "bc7955679916b089445c9dfb4bc597aa0daaf17d",
  "kind": "officer-list",
  "active_count": 4,
  "inactive_count": 0,
  "start_index": 0,
  "items": [
    {
      "officer_role": "llp-designated-member",
      "name": "BARRICK, David James",
      "date_of_birth": {
        "year": 1984,
        "month": 1
      },
      "appointed_on": "2017-09-15",
      "country_of_residence": "England",
      "address": {
        "country": "United Kingdom",
        "address_line_1": "Old Gloucester Street",
        "locality": "London",
        "premises": "27",
        "postal_code": "WC1N 3AX"
      },
      "links": {
        "officer": {
          "appointments": "/officers/d_PT9xVxze6rpzYwkN_6b7og9-k/appointments"
        }
      }
    },
    {
      "links": {
        "officer": {
          "appointments": "/officers/M2Ndc7ZjpyrjzCXdFZyFsykJn-U/appointments"
        }
      },
      "address": {
        "locality": "Tadcaster",
        "country": "United Kingdom",
        "address_line_1": "Westgate",
        "postal_code": "LS24 9AB",
        "premises": "5a"
      },
      "identification": {
        "legal_authority": "UK",
        "identification_type": "non-eea",
        "legal_form": "UK"
      },
      "name": "PREMIER DRIVER LIMITED",
      "officer_role": "corporate-llp-designated-member",
      "appointed_on": "2017-09-15"
    }
  ]
}

Я занимался созданием новых объектов json, извлекающих нужные мне поля, например:

{officer_address:.items[]?.address, appointed_on:.items[]?.appointed_on, country_of_residence:.items[]?.country_of_residence, officer_role:.items[]?.officer_role, officer_dob:items.date_of_birth, officer_nationality:.items[]?.nationality, officer_occupation:.items[]?.occupation}

Но запрос выполняется часами, и я уверен, что он есть.более быстрый способ.

Прямо сейчас я пробую этот новый подход - создание json, корнем которого является номер компании и в качестве аргумента список ее должностных лиц.

{(.links.self | split("/")[2]): .items[]}

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Используя jq, проще извлечь значения из объекта верхнего уровня, который будет использоваться совместно, и сгенерировать нужные строки.Вы захотите ограничить количество раз, которое вы просматриваете, максимум один раз.

$ jq -r '(.links.self | split("/")[2]) as $companyCode 
   | .items[]
   | [ $companyCode, .country_of_residence, .officer_role, .appointed_on ]
   | @csv
' input.json
0 голосов
/ 28 февраля 2019

Хорошо, вы хотите отсканировать список офицеров, извлечь из него некоторые поля, если они есть, и записать их в формате csv.

Первая часть - извлечь данные из json.Предполагая, что вы загрузили это объект data Python, у вас есть:

print(data['items'][0]['officer_role'], data['items'][0]['appointed_on'],
      data['items'][0]['country_of_residence'])

дает:

llp-designated-member 2017-09-15 England

Время собрать все вместе с модулем csv:

import csv
...
with open('output.csv', 'w', newline='') as fd:
    wr = csv.writer(fd)
    for officer in data['items']:
        _ = wr.writerow(('OC418979',
                 officer.get('country_of_residence',''),
                 officer.get('officer_role', ''),
                 officer.get('appointed_on', '')
                 ))

Метод get в словаре позволяет использовать значение по умолчанию (здесь пустая строка), если ключ отсутствует, а модуль csv гарантирует, что если поле содержит запятую, оно будет заключенов кавычках.

С вашим примером ввода, он дает:

OC418979,England,llp-designated-member,2017-09-15
OC418979,,corporate-llp-designated-member,2017-09-15
...