【问题标题】:Python json normalize API requestPython json 规范化 API 请求
【发布时间】:2020-08-03 12:19:09
【问题描述】:

我收到 JSON 格式的数据,但很难将它们转换成合适的格式。希望您能够帮助我。

import pandas as pd

from pandas.io.json import json_normalize

import requests

dataAPI = requests.get('here is the API URL')

print(dataAPI.json()) 

给我以下输出:

{'c': [277.775, 277.76, 277.65, 277.64, 277.5215], 'h': [277.89, 278.06, 277.98, 277.
76, 277.98], 'l': [277.67, 277.71, 277.59, 277.42, 277.472], 'o': [277.69, 277.795, 277.77, 277.66, 277.72], 's': 'ok', 't': [1587412320, 1587412380, 1587412440, 1587412500, 1587412560, 1587412620, ], 'v': [0, 142752, 133100, 259539, 0]}

我想创建一个包含以下列(跳过第 s 列)和浮动单元格值的数据框:

c| h| l| o| t| v

277.775| 277.89| 277.67| 277.69| 1587412320| 0

...

我尝试了一些类似 json_normalize(dataAPI, 'c') 的方法

但这给了我一条错误消息 TypeError: 字节索引必须是整数或切片,而不是 str

非常感谢您的帮助

【问题讨论】:

    标签: python json pandas normalize


    【解决方案1】:

    你必须定义你想要的列,而不仅仅是使用pandas.concat

    j = {'c': [277.775, 277.76, 277.65, 277.64, 277.5215], 'h': [277.89, 278.06, 277.98, 277.76, 277.98], 'l': [277.67, 277.71, 277.59, 277.42, 277.472], 'o': [277.69, 277.795, 277.77, 277.66, 277.72], 's': 'ok', 't': [1587412320, 1587412380, 1587412440, 1587412500, 1587412560, 1587412620, ], 'v': [0, 142752, 133100, 259539, 0]}
    columns = {'c', 'h', 'l',  'o', 't', 'v'}
    pd.concat([pd.DataFrame({k: v}) for k, v in j.items() if k in columns], axis=1)
    

    输出:

    【讨论】:

    • 我有时会收到以下错误: Traceback(最近一次调用最后一次):文件“test.py”,第 19 行,在 dfraw = pd.concat([pd.DataFrame( {k: v}) for k, v in dataAPI.json().items() if k in columns], axis=1) File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\ LocalCache\local-packages\Python38\site-packages\requests\models .py",第 898 行,在 json 中...从无 json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 有没有办法跳过这个错误
    • 我正在循环运行 API 请求...我假设服务器输出数据文件为空(这就是出现错误的原因)。有没有办法告诉 Python -> 如果遇到错误,继续循环
    【解决方案2】:
    dict1 = {'c': [277.775, 277.76, 277.65, 277.64, 277.5215],
             'h': [277.89, 278.06, 277.98, 277.76, 277.98],
             'l': [277.67, 277.71, 277.59, 277.42, 277.472],
             'o': [277.69, 277.795, 277.77, 277.66, 277.72],
             's': 'ok',
             't': [1587412320, 1587412380, 1587412440, 1587412500, 1587412560, 1587412560,],
             'v': [0, 142752, 133100, 259539, 0]}
    

    对于上述从 API 响应获得的输出,您可以执行以下操作:

    import pandas as pd
    
    df1 = pd.DataFrame.from_dict(dict1, orient="index").T.drop(columns=["s"])
    df1
    

    上面的代码将通过按索引定向从字典中创建一个数据框(如果字典中的列表值相等,也可以按列创建)然后转置它。删除将指示您要删除的任何列。

    输出:

    Out[21]: 
             c       h        l        o            t       v
    0  277.775  277.89   277.67   277.69   1587412320       0
    1   277.76  278.06   277.71  277.795   1587412380  142752
    2   277.65  277.98   277.59   277.77  1.58741e+09  133100
    3   277.64  277.76   277.42   277.66  1.58741e+09  259539
    4  277.522  277.98  277.472   277.72  1.58741e+09       0
    5      NaN     NaN      NaN      NaN  1.58741e+09     NaN
    

    您不想包含NaN,因此您也可以将dropna() 附加到代码中,如下所示:

    df1 = pd.DataFrame.from_dict(dict1, orient="index").T.drop(columns=["s"]).dropna()
    

    这样您就可以灵活地处理NaN 并删除不需要的列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 2016-02-04
      • 2021-04-26
      • 2022-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多