我有一个嵌套很深的 JSON,我正尝试使用 json_normalize 将其转换为 Pandas Dataframe。
我正在处理的 JSON 数据的 generic sample 看起来像这样(我在帖子底部添加了我正在尝试做的事情的上下文):
{
"per_page": 2,
"total": 1,
"data": [{
"total_time": 0,
"collection_mode": "default",
"href": "https://api.surveymonkey.com/v3/responses/5007154325",
"custom_variables": {
"custvar_1": "one",
"custvar_2": "two"
},
"custom_value": "custom identifier for the response",
"edit_url": "https://www.surveymonkey.com/r/",
"analyze_url": "https://www.surveymonkey.com/analyze/browse/",
"ip_address": "",
"pages": [
{
"id": "103332310",
"questions": [{
"answers": [{
"choice_id": "3057839051"
}
],
"id": "319352786"
}
]
},
{
"id": "44783164",
"questions": [{
"id": "153745381",
"answers": [{
"text": "some_name"
}
]
}
]
},
{
"id": "44783183",
"questions": [{
"id": "153745436",
"answers": [{
"col_id": "1087201352",
"choice_id": "1087201369",
"row_id": "1087201362"
}, {
"col_id": "1087201353",
"choice_id": "1087201373",
"row_id": "1087201362"
}
]
}
]
}
],
"date_modified": "1970-01-17T19:07:34+00:00",
"response_status": "completed",
"id": "5007154325",
"collector_id": "50253586",
"recipient_id": "0",
"date_created": "1970-01-17T19:07:34+00:00",
"survey_id": "105723396"
}
],
"page": 1,
"links": {
"self": "https://api.surveymonkey.com/v3/surveys/123456/responses/bulk?page=1&per_page=2"
}
}
我希望得到一个包含 question_id、page_id、response_id 和响应数据的数据框,如下所示:
choice_id col_id row_id text question_id page_id response_id
0 3057839051 NaN NaN NaN 319352786 103332310 5007154325
1 NaN NaN NaN some_name 153745381 44783164 5007154325
2 1087201369 1087201352 1087201362 NaN 153745436 44783183 5007154325
3 1087201373 1087201353 1087201362 NaN 153745436 44783183 5007154325
我可以通过运行以下代码(Python 3.6)来接近:
df = json_normalize(data=so_survey_responses['data'], record_path=['pages', 'questions'], meta='id', record_prefix ='question_')
print(df)
哪个返回:
question_answers question_id id
0 [{'choice_id': '3057839051'}] 319352786 5007154325
1 [{'text': 'some_name'}] 153745381 5007154325
2 [{'col_id': '1087201352', 'choice_id': '108720... 153745436 5007154325
但如果我尝试在更深的嵌套中运行 json_normalize 并保留上述结果中的“question_id”数据,我只能返回 page_id 值,而不是真正的 question_id 值:
answers_df = json_normalize(data=so_survey_responses['data'], record_path=['pages', 'questions', 'answers'], meta=['id', ['questions', 'id'], ['pages', 'id']])
print(answers_df)
返回:
choice_id col_id row_id text id questions.id pages.id
0 3057839051 NaN NaN NaN 5007154325 103332310 103332310
1 NaN NaN NaN some_name 5007154325 44783164 44783164
2 1087201369 1087201352 1087201362 NaN 5007154325 44783183 44783183
3 1087201373 1087201353 1087201362 NaN 5007154325 44783183 44783183
一个复杂的因素可能是以上所有(question_id、page_id、response_id)在 JSON 数据中都是“id:”。
我确信这是可能的,但我做不到。有关如何执行此操作的任何示例?
其他上下文: 我正在尝试创建 SurveyMonkey API response output 的数据框。
我的长期目标是重新创建 "all responses" excel sheet that their export service provides 。
我计划通过设置响应数据框(如上),然后使用 .apply() 将响应与他们的 survey structure API output 匹配来实现这一点。
我发现 SurveyMonkey API 在提供有用的输出方面相当乏善可陈,但我是 Pandas 的新手,所以它可能在我身上。
最佳答案
您需要修改最后一个选项的 meta
参数,并且,如果您想重命名列以完全按照您想要的方式命名,您可以使用 rename
:
answers_df = json_normalize(data=so_survey_responses['data'],
record_path=['pages', 'questions', 'answers'],
meta=['id', ['pages', 'questions', 'id'], ['pages', 'id']])\
.rename(index=str,
columns={'id': 'response_id', 'pages.questions.id': 'question_id', 'pages.id': 'page_id'})
关于python - 使用 pandas 和 json_normalize 来展平嵌套的 JSON API 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53198931/