我正在使用C3.ai的API来分析统一的COVID-19数据。为了在COVID爆发的各个位置生成确认病例和死亡的时间序列,我成功调用了evalMetrics
API,但是收到的响应是JSON
。
如何最好地将其转换为python中的pandas数据框,以便可以轻松地对此数据进行分析?
这是我用来成功调用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
转换为熊猫数据框。我可以使用通用函数将任何eval_metrics_result
转换为熊猫数据帧吗?
答案 0 :(得分:0)
执行此操作的一种方法如下:
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
的时间戳进行排序。
答案 1 :(得分:0)
还有另外两种方式来存储/获取数据框:
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)
# 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)
答案 2 :(得分:0)
您可以将c3covid19与docs here一起使用。它是用于Python的简单c3 covid19数据湖连接包装器。
安装
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 df。
相反,使用以下命令获取字典:
output_df=cnx.request(
data_type='outbreaklocation',
parameters=request_data,
api='evalmetrics',
output_type='objs'
)
然后按照Suraj或Jac在更具针对性的时间序列答案之一中列出的说明进行操作。