Нормализуйте / выровняйте очень глубоко вложенный JSON (в котором имена и свойства одинаковы для разных уровней) - PullRequest
1 голос
/ 06 ноября 2019

Я пытаюсь сгладить или нормализовать этот очень вложенный json в фрейм данных с пандами.

Проблема в том, что на каждом уровне имена и свойства совпадают.

Я не нашел ни одного вопроса панды, похожего на этот. Но я вижу 2 похожих вопроса, но они написаны на R и JavaScript: Нормализация глубоко вложенных объектов и Нормализация глубоко вложенных объектов Я не знаю, можете ли вы вдохновиться этим.

Мой оригинальный файл 40M. Вот пример этого:

data = [
  {
    "id": "haha",
    "type": "table",
    "composition": [
      {
        "id": "AO",
        "type": "basket",
      },
      {
        "id": "KK",
        "type": "basket",
#         "isAutoDiv": false,
        "composition": [
          {
            "id": "600",
            "type": "apple",
            "num": 1.116066714
          },
          {
            "id": "605",
            "type": "apple",
            "num": 1.1166976714
          }
        ]
      }
    ]
  },
  {
    "id": "hoho",
    "type": "table",
    "composition": [
      {
        "id": "KT",
        "type": "basket"
      },
      {
        "id": "OT",
        "type": "basket"
      },
      {
        "id": "CL",
        "type": "basket",
#         "isAutoDiv": false,
        "composition": [
          {
            "id": "450",
            "type": "apple"
          },
          {
            "id": "630",
            "type": "apple"
          },
          {
            "id": "023",
            "type": "index",
            "composition": [
              {
                "id": "AAOAAOAOO",
                "type": "applejuice"
              },
              {
                "id": "MMNMMNNM",
                "type": "applejuice"
              },
            ]
          }
        ]
      }
    ]
  }
]

Видите? Имена и свойства одинаковы на всех уровнях.

Я использовал эту строку, чтобы нормализовать ее. Но я не знаю, как нормализовать объекты, вложенные во вложенные объекты, когда они имеют одинаковые имена и свойства:

df = json_normalize(data, record_path = ['composition'], meta = ['id', 'type'], record_prefix = 'compo_')
                                   compo_composition compo_id compo_type id     type
0                                                NaN      AO    basket  haha    table
1   [{'id': '600', 'type': 'apple', 'num': 1.11606...     KK    basket  haha    table
2                                                NaN      KT    basket  hoho    table
3                                                NaN      OT    basket  hoho    table
4   [{'id': '450', 'type': 'apple'}, {'id': '630',...     CL    basket  hoho    table

Вы видите в столбце "compo_composition", что они все еще являются вложеннымиобъекты.

Теперь я хочу, чтобы в нем были следующие столбцы:

compo_compo_compo__id   compo_compo_compo_type   compo_compo__id   compo_compo_type   compo_id  compo_type  id  type

Тонны благодарностей. Это расстраивает меня в течение нескольких дней, и я нигде не нашел ответа.

1 Ответ

0 голосов
/ 07 ноября 2019

Вы должны написать свой собственный парсер. Предполагается, что (a) ваш JSON имеет невероятную глубину и (b) каждый элемент на пути уникален (ala table > basket > index, а не table > table > basket)

# Make a copy so we do not change the original data
tmp = data.copy()
compositions = []

while len(tmp) > 0:
    item = tmp.pop(0)

    if 'composition' in item:
        # If a level has children, add that level's `id` 
        # to the path and process its children
        path = item.get('path', {})
        path[item['type'] + '_id'] = item['id']

        children = [
            {'path': path, **child} for child in item.get('composition', [])
        ]
        tmp += children
    else:
        # If a level has no child, we are done
        compositions += [item]

И окончательный кадр данных:

df = pd.DataFrame([c['path'] for c in compositions]) \
        .join(pd.DataFrame(compositions)) \
        .drop(columns='path')

Результат:

  table_id basket_id index_id         id        type       num
0     haha        KK      NaN         AO      basket       NaN
1     hoho        CL      023         KT      basket       NaN
2     hoho        CL      023         OT      basket       NaN
3     haha        KK      NaN        600       apple  1.116067
4     haha        KK      NaN        605       apple  1.116698
5     hoho        CL      023        450       apple       NaN
6     hoho        CL      023        630       apple       NaN
7     hoho        CL      023  AAOAAOAOO  applejuice       NaN
8     hoho        CL      023   MMNMMNNM  applejuice       NaN
...