Большой вложенный JSON в панды DataFrame Python - PullRequest
0 голосов
/ 29 октября 2018

У меня есть большой вложенный объект json, который я хотел бы прочитать в кадре данных pandas. У объекта json много вложенных пар json. Основное наслоение:

  • метаданные вызова API (мне это безразлично)
  • Метаданные ответа на опрос (я хотел бы, чтобы эта информация была включена в окончательный вывод)
  • Страницы (страницы опроса с идентификационным номером и какие вопросы есть на этой странице)
  • Вопросы (question_ids и соответствующие response_ids из вопросов)

Пример выглядит так:

{
    "per_page": 50,
    "total": 4,
    "data": [
        {
            "total_time": 5276,
            "href": "https://somelink.com",
            "custom_variables": {},
            "ip_address": "XXX.XXX.XX.XX",
            "id": "1111111",
            "logic_path": {},
            "date_modified": "2018-08-17T19:57:43+00:00",
            "response_status": "completed",
            "custom_value": "",
            "analyze_url": "https://somelink.com/respondent_id=1111111",
            "pages": [
                {
                    "id": "38638937",
                    "questions": []
                },
                {
                    "id": "38638938",
                    "questions": [
                        {
                            "id": "124810659",
                            "answers": [
                                {
                                    "text": "some_answer_text"
                                }
                            ]
                        },
                        {
                            "id": "124810660",
                            "answers": [
                                {
                                    "text": "some_other_answer_text"
                                }
                            ]
                        }
                    ]
                },
                {
                    "id": "38638944",
                    "questions": [
                        {
                            "id": "124810656",
                            "answers": [
                                {
                                    "col_id": "905794209",
                                    "choice_id": "905794459",
                                    "row_id": "905794204"
                                },
                                {
                                    "col_id": "905794210",
                                    "choice_id": "905794463",
                                    "row_id": "905794204"
                                },
                                {
                                    "col_id": "905794209",
                                    "choice_id": "905794459",
                                    "row_id": "905794205"
                                },
                                {
                                    "col_id": "905794210",
                                    "choice_id": "905794464",
                                    "row_id": "905794205"
                                }
                            ]
                        }
                    ]   
                }
                .
                .
                .
                .
                .
                .
                .
                .
            ],
            "page_path": [],
            "recipient_id": "4107168056",
            "collector_id": "216279750",
            "date_created": "2018-09-05T15:28:38+00:00",
            "survey_id": "222222222",
            "collection_mode": "default",
            "edit_url": "https://www.somelink.com/somerefnumber",
            "metadata": {
                "contact": {
                    "email": {
                        "type": "string",
                        "value": "name@somememail.com"
                    }
                }
            }
        },
        {
            "total_time": 6978,
            "href": "https://somelink.com",
            "custom_variables": {},
            "ip_address": "XXX.XXX.XX.XX",
            "id": "4444444",
            "logic_path": {},
            "date_modified": "2018-08-15T19:16:43+00:00",
            "response_status": "completed",
            "custom_value": "",
            "analyze_url": "https://somelink.com/respondent_id=4444444",
            "pages": [
                    .
                    .
                    .

            ]
        }

    ],
    "page": 1,
    "links": {
        "self": "https://api.somelink.com/22222222/responses/bulk?page=1&per_page=50"
    }
}

На странице может быть любое количество ответов, страниц и вопросов.

Мой вопрос: Как я могу получить вышеупомянутый JSON в DataFame Pandas, который выглядит следующим образом: Formatted Pandas dataframe (as excel for reference)

Я пытался использовать json_normalize , но мне кажется, что я делаю некоторые ошибки.

import pandas as pd
import requests
from pandas.io.json import json_normalize

headers={"Authorization": "Bearer %s" % MY_ACCESS_TOKEN,
                           "Content-Type": "application/json"}

url = "https://api.surveymonkey.com/v3/surveys/%s/responses/bulk" % (my_survey_id)
response = requests.get(url, headers=headers)
responses = response.json()

pages_data = json_normalize(data=responses['data'], record_path='pages', meta=['response_status', 'recipient_id', 'collector_id', 'survey_id', 'date_created', 'date_modified', 'ip_address', 'href', 'total_time'])
print(pages_data.head(10))
pages_data.to_csv("output.csv")

Как дополнительная информация, это из SurveyMonkey API . SurveyMonkey позволяет вам экспортировать результаты опроса в csv через веб-интерфейс , но я бы хотел использовать API для повторного создания стандартного отчета об ответах и, в конечном итоге, для создания пользовательских отчетов / других действий.

Я использую python3.6. Я предполагаю, что мне нужно выполнить некоторую предварительную обработку, чтобы сгладить данные, но я не уверен, как это сделать. Любая помощь приветствуется!

1 Ответ

0 голосов
/ 30 октября 2018

Конвертируйте ваш JSON в фрейм данных:

df = pd.DataFrame(json)

после

df = df.to_csv(file, sep='\t')
...