无法将 JSON 转换为 pandas。所有数据都包含在一行中。我该如何解压它?

Trouble converting JSON to pandas. All of the data is contained in one row. How do I unpack it?

我正在尝试将 JSON 文件转换为 pandas 数据框,但是,虽然列看起来正确,但所有数据都包含在一行中,而不是我的意图是一个时间序列,索引为 'Fiscal Year'

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 个不同的年份。如有任何建议,我们将不胜感激!

这远远超出了 pandas 自动 Json 处理的范围:您的 json 是一个复杂的结构,最多有 2 个关键级别,并且只有大小为 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)