【问题标题】:Trouble converting JSON to pandas. All of the data is contained in one row. How do I unpack it?无法将 JSON 转换为 pandas。所有数据都包含在一行中。我该如何解压它?
【发布时间】: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 个唯一年份。任何建议将不胜感激!

【问题讨论】:

  • 您能否提供数据样本以便于复制?

标签: python json pandas nested flatten


【解决方案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即可。
  • 完美运行。感激不尽!
猜你喜欢
  • 2020-03-24
  • 1970-01-01
  • 2020-10-31
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2019-05-14
  • 2017-10-19
相关资源
最近更新 更多