我们想从IMF网站获取数据并将其转储到csv文件中。使用IMF为此目的发布的API完成数据的获取。但是,检索到的json列表包含一个嵌套字典,该字典可能为空或具有不同数量的元素,具体取决于数据不为空的年份。 以下是为查明问题而创建的代码段。我们正在通过Jupyter Notebook使用python 3.6.5
我们尝试使用json_normalize,但是它只能将顶级转换为csv。 JSON的第二个元素包含一个嵌套的字典,这会导致不希望的输出。
import requests
from pandas.io.json import json_normalize
#url = 'http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/IFS/A.AU..?startPeriod=2017&endPeriod=2019'
url = 'http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/IFS/A.AU.FDSBT_XDC+GG_GEG_G01_XDC+FFSE_XDC.?startPeriod=2017&endPeriod=2019'
# Navigate to series in API-returned JSON data
json_raw = (requests.get(f'{url}').json()['CompactData']['DataSet']['Series'])
json_normalize(json_raw)
json_normalize的输出结果为(观察到包含嵌套字典数组的'Obs'引起了问题)
@FREQ @INDICATOR @REF_AREA @TIME_FORMAT @UNIT_MULT Obs Obs.@OBS_VALUE Obs.@TIME_PERIOD
0 A FFSE_XDC AU P1Y 6 NaN 15750.23064215 2017
1 A GG_GEG_G01_XDC AU P1Y 6 [{'@TIME_PERIOD': '2017', '@OBS_VALUE': '4168'}, {'@TIME_PERIOD': '2018', '@OBS_VALUE': '3443'}] NaN NaN
2 A FDSBT_XDC AU P1Y 6 NaN NaN NaN
我们希望得到如下结果,以便可以将结构化格式转储到csv
@FREQ @INDICATOR @REF_AREA @TIME_FORMAT @UNIT_MULT Obs.@OBS_VALUE_0 Obs.@TIME_PERIOD_0 Obs.@OBS_VALUE_1 Obs.@TIME_PERIOD_1
0 A FFSE_XDC AU P1Y 6 15750.23064215 2017 NaN NaN
1 A GG_GEG_G01_XDC AU P1Y 6 4168 2017 3443 2018
2 A FDSBT_XDC AU P1Y 6 NaN NaN NaN NaN
答案 0 :(得分:0)
这可能会帮助
def get_details_in_csv(jsonData):
csvio = io.StringIO()
names = ['Account Number', 'Account Name', 'Region', 'SG', 'Inbound port', 'Inbound IP', 'Assessment']
writer = csv.DictWriter(csvio, fieldnames=names)
writer.writeheader()
for security_group in jsonData['SecurityGroups']:
groupId = security_group["GroupId"]
for inboundEntry in security_group["InboundDetails"]:
inboundPort = inboundEntry['port']
inboundIP = inboundEntry['source']
assessment = inboundEntry['assessment']
writer.writerow({'Account Number': ACCOUNT_NUMBER, 'Account Name': ACCOUNT_NAME, 'Region': REGION,
'SG': groupId, 'Inbound port': inboundPort,
'Inbound IP': inboundIP, 'Assessment': assessment})
response = csvio.getvalue()
print(csvio.getvalue())
csvio.close()
return response