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

Posted

技术标签:

【中文标题】无法将 JSON 转换为 pandas。所有数据都包含在一行中。我该如何解压它?【英文标题】:Trouble converting JSON to pandas. All of the data is contained in one row. How do I unpack it? 【发布时间】:2019-10-27 03:09:56 【问题描述】:

我正在尝试将 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】:

这远远超出了 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)

【讨论】:

感谢您对 Serge 的评论。我在“flat=”行之后立即插入您的代码并收到以下错误消息... NameError: name 'collections' is not defined collections 是标准库中的一个包。使用前添加import collections即可。 完美运行。感激不尽!

以上是关于无法将 JSON 转换为 pandas。所有数据都包含在一行中。我该如何解压它?的主要内容,如果未能解决你的问题,请参考以下文章

无法将 groupby 数据集转换为 pandas 中的 json [重复]

快速将 JSON 列转换为 Pandas 数据框

如何将分层表转换为json

将嵌套 JSON 转换为 pandas DataFrame

无法将字符串转换为 pandas 中的浮点数(ValueError)

将 pandas 数据帧转换为 json 对象 - pandas