【问题标题】:Troubleshooting format of JSON get requestJSON get请求的疑难解答格式
【发布时间】:2020-02-06 19:39:41
【问题描述】:

我在尝试将获取请求响应转换为我想要的格式时遇到了问题。 JSON 响应的结构有点复杂,我无法将其转换为正确的格式。

这是我将 json 脚本转换为 pandas 数据框的代码:

data = pd.DataFrame.from_dict(resp_isrc.json())
data.head() 

这是我得到的 JSON 结构如下:

{"country":"US",
 "artist_name":"Frank Ocean",
 "title_name":"Provider",
 "release_date":"2017-08-25",
 "core_genre":"R&B/Hip-Hop",
 "metrics":[{"name":"ISRC w/SES On-Demand",
             "value":[{"name":"tp","value":2810},
                      {"name":"lp","value":2450},
                      {"name":"ytd","value":2740},
                      {"name":"atd","value":554267}]},

【问题讨论】:

  • 你需要从女巫列中的 Json 文件中获取哪些数据?
  • @ZarakiKenpachi 我正在尝试在他们自己的列中获取“流式点播音频”下的“tp”和“lp”值
  • 您可能需要先展平 json,然后再将其弹出到数据框中。简单的事情,例如将字典列表更改为字典。例如,{"ISRC w/SES On-Demand":{"tp":2810, "lp":2450, "ytd":2740, "atd":554267},...}
  • @Tim 所以我尝试通过这样做 df​​ = pd.DataFrame.from_dict(resp_isrc) 来展平 json,但格式似乎不正确。

标签: python json pandas get request


【解决方案1】:

可能需要进行一些预处理才能达到您想要的效果。这对于来自请求的 json 结果来说是相当典型的。在某些情况下,可以使用更通用的方法。但在这里,由于结构相当简单,指标可以很容易地展平。

def flatten2df(resp_isrc, df=None):
    metrics = resp_isrc.pop('metrics')
    flattened_json = []
    for item in metrics:
        metric = item['name']
        values = item['value']
        new_entry = {entry['name']: entry['value'] for entry in values}
        new_entry.update({'metric': metric})
        new_entry.update(resp_isrc)
        flattened_json.append(new_entry)
    new_df = pandas.DataFrame(flattened_json)
    if df is None:
        return new_df
    return df.append(new_df, ignore_index=True)

如果有多个请求,可以循环过去

df = pandas.DataFrame()

for i in lst:
    response = requests.get(...)
    df = flatten2df(response.json(), df)

更快:

首先将所有展平的结果附加到列表中,然后输入到数据框中。

def flatten2list(resp_isrc, flattened_json):
    metrics = resp_isrc.pop('metrics')
    for item in metrics:
        metric = item['name']
        values = item['value']
        new_entry = {entry['name']: entry['value'] for entry in values}
        new_entry.update({'metric': metric})
        new_entry.update(resp_isrc)
        flattened_json.append(new_entry)

如果有多个请求,可以循环过去

results = []

for i in lst:
    response = requests.get(...)
    flatten2list(response.json(), results)

df = pandas.DataFrame(results)

【讨论】:

  • 嘿蒂姆!感谢您的帮助。那么'metrics = resp_isrc.pop(metrics)'是否从json的其余部分解析'metrics'?我收到 AttributeError: 'Response' object has no attribute 'pop'
  • 您可能首先需要 resp_isrc=resp_isrc.json()。 pop 是一个字典方法,从字典中移除并返回键值对。
  • 太棒了!最后一件事,你知道如何转置'name;列,以便 tp、lp、ytd 和 atd 是它们自己的列,并具有相应的值?
  • 更新的答案,现在应该给你列
  • 嘿,蒂姆,这非常有效!尽管现在添加了多个 json 请求,但 df 仅返回最后一个请求的数据。不确定这是否可能,但是关于如何将多个请求输出到 df 的任何想法?
【解决方案2】:

这里如何从 json 字典中提取 name, ip lp 数据:

import pandas as pd

data = []
for item in raw_data.get('metrics'):
    tp = 0
    lp = 0
    for name in item.get('value'):
        if 'tp' in name.values():
            tp = name.get('value')
        if 'lp' in name.values():
            lp = name.get('value')
    data.append([item.get('name'), tp, lp])

df = pd.DataFrame(data, columns=['name', 'ip', 'lp'])

输出:

                         name      ip      lp
0        ISRC w/SES On-Demand    2810    2450
1  ISRC w/SES On-Demand Audio    2735    2384
2              Digital Tracks      21      19
3   Streaming On-Demand Total  395705  348276
4   Streaming On-Demand Audio  367707  323399
5   Streaming On-Demand Video   27998   24877
6  Streaming Programmed Total     187     153

【讨论】:

  • 所以当我运行这个时,我最终得到这个 AttributeError: 'list' object has no attribute 'get'。正如上面的 cmets 中提到的,我必须在将 JSON 放入 df 之前将其“展平”,所以也许这就是我们收到此错误的原因?
  • @KirklandShawty raw_data 被定向到您发布的 Jonson。错误是因为您的数据在字典列表中..
猜你喜欢
  • 2012-11-16
  • 2013-01-29
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 2014-08-29
相关资源
最近更新 更多