Как преобразовать результат evalmetrics C3.ai COVID-19 API в pandas фрейм данных для более удобного анализа? - PullRequest
2 голосов
/ 14 апреля 2020

Я использую API C3.ai для анализа унифицированных данных COVID-19. Для генерации временных рядов подтвержденных случаев и смертей в разных местах вспышек COVID я успешно вызвал API evalMetrics, но полученный ответ JSON.

Как лучше всего преобразовать это в pandas фрейм данных в python, чтобы я мог легко выполнить мой анализ этих данных?

Вот код, который я использовал для вызова evalMetrics API успешно:

import json, requests
locations_to_evaluate = ["China","Italy"]
expressions_to_evaluate = ["JHU_ConfirmedCases","JHU_ConfirmedDeaths"]
url = "https://api.c3.ai/covid/api/1/outbreaklocation/evalmetrics/"
request_data = {
    "spec": {
        "ids": locations_to_evaluate,
        "expressions": expressions_to_evaluate,
        "start": "2020-02-01",
        "end": "2020-03-01",
        "interval": "DAY"
    }
}
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json"
}
response = requests.post(url=url, json=request_data, headers=headers)
eval_metrics_result = json.loads(response.text)

Я хочу преобразовать eval_metrics_result в pandas фрейм данных. Есть ли общая функция c, которую я могу использовать для преобразования любого eval_metrics_result в pandas фрейм данных?

Ответы [ 3 ]

0 голосов
/ 16 апреля 2020

Вот два других способа сохранить / захватить как фрейм данных:

  1. Широкоформатный формат с оценкой_идентификатора, выражением, массивом дат, массивом данных.
import pandas as pd

# get as a wide df with evaluate_id, expression, dates array, data array
evaluate_ids = list(eval_metrics_result['result'].keys())
expressions  = list(eval_metrics_result['result'][evaluate_ids[0]].keys())
formatted_list = [{'evaluate_id':evaluate_id,
                  'expression':expression, 
                  'dates': pd.to_datetime(eval_metrics_result['result'][evaluate_id][expression]['dates']),
                  'data': eval_metrics_result['result'][evaluate_id][expression]['data']} 
                                          for evaluate_id in evaluate_ids for expression in expressions]
wide_df = pd.DataFrame(formatted_list)
Длинный формат - в основном такой же, как у Сураджа, но вместо этого, valu_id и выражение хранятся в своих собственных столбцах. Это помогает DF хорошо играть с групповым.
# convert from wide to long format
wide_df['dates-data'] = wide_df.apply(lambda row: zip(row['dates'], row['data']), axis = 1)
wide_df.drop(columns = ['dates', 'data'])

def wide2long(df, list_col):
    a = pd.DataFrame(df[list_col].tolist()).stack().reset_index(level = 1, drop = True).rename(list_col)
    return df.drop(list_col, axis = 1).join(a).reset_index(drop = True)[df.columns]

long_df              = wide2long(wide_df, 'dates-data')
long_df['date']      = long_df['dates-data'].apply(lambda date_data: date_data[0])
long_df['data']      = long_df['dates-data'].apply(lambda date_data: date_data[1])
long_df.drop(columns = ['dates-data'], inplace = True)
0 голосов
/ 17 апреля 2020

Вы можете использовать c3covid19 с документами здесь . Это простая оболочка соединения c3 covid19 озера данных для python.

Установка

pip install c3covid19

Запуск

from c3covid19 import c3api

cnx=c3api()

locations_to_evaluate = ["China","Italy"]
expressions_to_evaluate = ["JHU_ConfirmedCases","JHU_ConfirmedDeaths"]
request_data = {
    "spec": {
        "ids": locations_to_evaluate,
        "expressions": expressions_to_evaluate,
        "start": "2020-02-01",
        "end": "2020-03-01",
        "interval": "DAY"
    }
}

output_df=cnx.request(
    data_type='outbreaklocation', 
    parameters=request_data, 
    api='evalmetrics', 
    output_type='pd'
)

Это простое преобразование в pandas, хотя , Отлично работает со списком словарей, но борется с более вложенной структурой. Вероятно, вам следует конвертировать в правильно отформатированный pandas df. ​​

Вместо этого используйте следующее, чтобы получить словарь:

output_df=cnx.request(
    data_type='outbreaklocation', 
    parameters=request_data, 
    api='evalmetrics',
    output_type='objs'
)

Затем следуйте инструкциям, перечисленным на одном из более целевые ответы временного ряда Сураджем или Джа c.

0 голосов
/ 14 апреля 2020

Один из способов сделать это будет следующим:

import pandas as pd
def convert_evalMetrics_to_Pandas(eval_metrics_result):
    evaluate_ids = list(eval_metrics_result["result"].keys())
    evaluate_metrics = list(eval_metrics_result["result"][evaluate_ids[0]].keys())
    timestamps = eval_metrics_result["result"][evaluate_ids[0]][evaluate_metrics[0]]["dates"]
    df = pd.DataFrame(
        columns = ["Evaluate_ID"]+evaluate_metrics,
        index = ["{}#{}".format(evaluate_id,timestamp) for evaluate_id in evaluate_ids for timestamp in timestamps]
    )
    df["Evaluate_ID"] = df.index.str.split("#").str[0]
    for evaluate_id in evaluate_ids:
        for evaluate_metric in evaluate_metrics:
            df[evaluate_metric].loc[df["Evaluate_ID"]==evaluate_id] = eval_metrics_result["result"][evaluate_id][evaluate_metric]["data"]
    df.drop("Evaluate_ID", axis=1, inplace=True)
    return df

Обратите внимание, что в этом случае индекс кадра данных будет иметь формат: id#timestamp Отметки времени для одного id будут быть заказанным до того, как индекс кадра данных перейдет к следующему id для тех же временных отметок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...