我正在尝试将深度嵌套的JSON转换为pandas dataframe

时间:2019-04-16 19:01:49

标签: python json pandas

我正在尝试将从API调用返回的json转换为pandas数据框。理想情况下,我只想提取“类型”,“名称”和“供应”。

我尝试了多种操作,例如flatten()json_normalize()等,但无法使其正常工作。

def get_cryptocompare_data():
    url = "https://min-api.cryptocompare.com/data/top/mktcapfull?limit=15&tsym=USD"
    data = requests.get(url)
    d = data.json()

我想将其转换为pandas数据框,其中包含“类型”,“名称”,“供应”的列。

3 个答案:

答案 0 :(得分:0)

在处理像这样的大量嵌套的JSON时,我更喜欢旧方法(for循环),因为它易于理解。

import pandas as pd

records = []

for item in d["Data"]:
    records.append(
        {
            "Type": item["CoinInfo"]["Type"],
            "Name": item["CoinInfo"]["Name"],
            "SUPPLY": item["RAW"]["USD"]["SUPPLY"],
        }
    )


df = pd.DataFrame.from_records(records)

df.head()

我没有将Type设置为索引,因为我不确定为什么要Type作为索引,因为它只有1个值。如果您需要将Type设置为索引,只需添加df.set_index("Type", inplace=True)

答案 1 :(得分:0)

这里的目标是将data.json()返回的dict展平的requests

平移词典是一个相当复杂的主题,因为可以在其中找到各种类型的值。但是在这里,数据馈送是已知的。

因此,可以从各种python配方中找到一个简单的展平函数,并将其功能性地应用于从数据提要中获得的数据。

import json
import itertools
import requests
import json
import pandas as pd

def get_cryptocompare_data():
    url = "https://min-api.cryptocompare.com/data/top/mktcapfull?limit=15&tsym=USD"
    response = requests.get(url)
    d = response.json()
    return d

# https://codereview.stackexchange.com/questions/21033/flatten-dictionary-in-python-functional-style
def flatten_dict(d):
    def items():
        for key, value in d.items():
            if isinstance(value, dict):
                for subkey, subvalue in flatten_dict(value).items():
                    yield key + "." + subkey, subvalue
            else:
                yield key, value

    return dict(items())

d = get_cryptocompare_data()
data = d['Data']
data = list(map(flatten_dict, data))
df = pd.DataFrame(data)
print(df[['CoinInfo.Name', 'CoinInfo.Type', 'RAW.USD.TYPE', 'RAW.USD.SUPPLY', 'DISPLAY.USD.SUPPLY']])

将提供以下名称,类型和供应列

  CoinInfo.Name  CoinInfo.Type RAW.USD.TYPE  RAW.USD.SUPPLY    DISPLAY.USD.SUPPLY
0           BTC              1            5    1.764898e+07        Ƀ 17,648,975.0
1           XRP              1            5    9.999185e+10  XRP 99,991,850,794.0
2           ETH              1            5    1.056861e+08       Ξ 105,686,063.1
3           EOS              1            5    1.041886e+09   EOS 1,041,886,454.0
4           BCH              1            5    1.764895e+07      BCH 17,648,946.0
5           LTC              1            5    6.136893e+07        Ł 61,368,933.6
6           BNB              1            5    1.883456e+08     BNB 188,345,602.2
7          USDT              1            5    2.468906e+09     ₮ 2,468,905,774.0
8           XLM              1            5    1.932851e+10  XLM 19,328,512,453.0
9           ADA              1            5    2.592707e+10  ADA 25,927,070,538.0

答案 2 :(得分:0)

Jmespath可以在此处帮助解决嵌套路径-基本摘要是,如果您遇到列表,请用方括号([]表示,如果是键,请使用点符号({ {1}}):

.

读入数据

import requests
url = "https://min-api.cryptocompare.com/data/top/mktcapfull?limit=15&tsym=USD"
data = requests.get(url).json()

#example : access the name key :
#path : Data -> list -> CoinInfo(dict) ->Name(dict)
#representation : Data[].CoinInfo.Name
#in words : Data, then list, then CoinInfo key, then Name key

import jmespath
expression = jmespath.compile('''{name:Data[].CoinInfo.Name,
                                  type:Data[].CoinInfo.Type,
                                  supply:Data[].RAW.USD.SUPPLY}''')
res = expression.search(data)