Проблема преобразования JSON в панд.Все данные содержатся в одной строке.Как мне его распаковать? - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь преобразовать файл JSON в кадр данных pandas, хотя столбцы выглядят правильно, все данные содержатся в одной строке, вместо того, чтобы я хотел, чтобы это был временной ряд с индексом ' Финансовый год '

import pandas as pd
import numpy as np
import urllib.request, json
from pandas.io.json import json_normalize

response = urllib.request.urlopen('https://api.gurufocus.com/public/user/f97abc68a0f96617ccea854faeff6db:ca86e5ff8d37550212f9c7d45645d413/stock/WMT/financials')

content = response.read()

data = json.loads(content.decode('utf8'))

data = (data['financials']['annuals'])

data = json_normalize(data)

df = pd.DataFrame(data)

df = pd.io.json.json_normalize(data)
print(df)

Вывод выглядит как df с правильными столбцами, но только одна строка, и для каждого столбца должно быть не менее 30 уникальных лет. Любые предложения будут с благодарностью!

1 Ответ

1 голос
/ 13 июня 2019

Это намного больше, чем может сделать автоматическая обработка Json от pandas: ваш json представляет собой сложную структуру с двумя ключевыми уровнями и содержит только списки размером 30 или 31.

В этот момент забудьте json_normalize и запустите ручной анализ.

Первый проход, сгладьте словарь:

def flatten(data):
    flat = {}
    for k, v in data.items():
        if isinstance(v, dict):
            for j, u in flatten(v).items():
                flat[k+'-'+j] = u
        else:
            flat[k] = v
    return flat

data2 = flatten(data)

Управляйте тем, что у нас теперь есть список списков, и контролируйте размеры списков:

c = collections.Counter()
for k,v in data2.items():
    if isinstance(v, list):
        c[len(v)] += 1
    else:
        print('============', k, type(v))

Хорошо, только списки из 31 элемента, кроме одного: добавьте None, чтобы сделать все списки равными по длине:

for k,v in data2.items():
    if len(v) == 30:
        v.append(None)

Теперь у нас есть словарь списков равной длины: это подходит дляпостроить фрейм данных:

df = pd.DataFrame(data2)
...