Как разобрать универсальный или любой JSON в CSV с помощью Python - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть несколько файлов JSON, которые нужно проанализировать в CSV.
Ниже приведен мой код:

import json
from collections import defaultdict
def flatten_json1(y):
    out = defaultdict(list)
    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], a )
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name )
                i += 1
        else:
            out[name].append(x)

    flatten(y)
    return out


import json
from pprint import pprint
with open('testjson.json') as f:
    data = json.load(f)

pprint(flatten_json1(data))

И это пример JSON, который я использую:

{
   "id": "0001",
   "type": "donut",
   "name": "Cake",
   "ppu": 0.55,
   "batters":
   {
      "batter":
      [
         { "id": "1001", "type": "Regular" },
         { "id": "1002", "type": "Chocolate" },
         { "id": "1003", "type": "Blueberry" },
         { "id": "1004", "type": "Devil's Food" }
      ]
   },
   "topping":
   [
      { "id": "5001", "type": "None" },
      { "id": "5002", "type": "Glazed" },
      { "id": "5005", "type": "Sugar" },
      { "id": "5007", "type": "Powdered Sugar" },
      { "id": "5006", "type": "Chocolate with Sprinkles" },
      { "id": "5003", "type": "Chocolate" },
      { "id": "5004", "type": "Maple" }
   ]
}

При запуске он дает мне следующий вывод:

defaultdict(<type 'list'>, {u'type': [u'None', u'Glazed', u'Sugar', 
u'Powdered Sugar', u'Chocolate with Sprinkles', u'Chocolate', u'Maple', 
u'Regular', u'Chocolate', u'Blueberry', u"Devil's Food", u'donut'], 
u'id': [u'5001', u'5002', u'5005', u'5007', u'5006', u'5003', u'5004', 
u'1001', u'1002', u'1003', u'1004', u'0001'], u'ppu': [0.55], u'name': 
[u'Cake']})

Но, как вы можете видеть, атрибут «ppu» и «name» не имеет размера списка, равного двум другим клавишам.

Итак, как я могу сделать это, как показано ниже:

defaultdict(<type 'list'>, {u'type': [u'None', u'Glazed', u'Sugar', 
u'Powdered Sugar', u'Chocolate with Sprinkles', u'Chocolate', u'Maple', 
u'Regular', u'Chocolate', u'Blueberry', u"Devil's Food", u'donut'], 
u'id': [u'5001', u'5002', u'5005', u'5007', u'5006', u'5003', u'5004', 
u'1001', u'1002', u'1003', u'1004', u'0001'], u'ppu': 
[0.55,0.55,0.55,0.55,0.55,0.55,0.55,0.55,0.55,0.55,0.55,0.55], u'name': [u'Cake’,u'Cake'u'Cake'u'Cake'u'Cake'u'Cake'u'Cake'u'Cake'u'Cake'u'Cake'u'Cake'u'Cake']})

Который имеет длину 12 каждый.Пожалуйста, помогите.

Заранее спасибо.

1 Ответ

0 голосов
/ 23 ноября 2018

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

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

def flatten_json(data):
    result = defaultdict(list)

    def flatten(x, name=""):
        if type(x) is dict:
            for k, v in x.items():
                flatten(v, k)
        elif type(x) is list:
            for v in x:
                flatten(v, name)
        else:
            result[name].append(x)

    flatten(data)
    max_length = max([len(v) for v in result.values()])

    for v in result.values():
        if max_length - len(v) == 1:
            v.insert(0, "")

        v.extend([v[-1]] * (max_length - len(v)))

    return result

Вывод:

defaultdict(<class 'list'>,
            {'id': ['0001', '1001', '1002', '1003', '1004', '5001', '5002',
                    '5005', '5007', '5006', '5003', '5004'],
             'name': ['Cake', 'Cake', 'Cake', 'Cake', 'Cake', 'Cake', 'Cake',
                      'Cake', 'Cake', 'Cake', 'Cake', 'Cake'],
             'ppu': [0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55,
                     0.55, 0.55],
             'type': ['donut', 'Regular', 'Chocolate', 'Blueberry',
                      "Devil's Food", 'None', 'Glazed', 'Sugar',
                      'Powdered Sugar', 'Chocolate with Sprinkles', 'Chocolate',
                      'Maple']})

и

defaultdict(<class 'list'>,
            {'active': [False, True, True, True, False, True],
             'ages': ['123', '123', '123', '123', '123', '123'],
             'availableDate': ['2018-24-11', '2018-24-12', '2018-24-13',
                               '2018-24-14', '2018-24-15', '2018-24-16'],
             'build': ['Jack12', 'Jack12', 'Jack12', 'Jack12', 'Jack12',
                       'Jack12'],
             'country': ['', 'IND1', 'IND2', 'IND3', 'IND4', 'IND5'],
             'hierID': ['jack', 'jack', 'jack', 'jack', 'jack', 'jack'],
             'locID': ['Jack123', 'Jack123', 'Jack123', 'Jack123', 'Jack123',
                       'Jack123'],
             'org': ['', 'jack1', 'jack2', 'jac3', 'jack4', 'jack5']})

Попробуйте!

...