如何将FastAPI中的Pydantic模型转换为Pandas DataFrame?

4

我正在尝试将 Pydantic 模型转换为 Pandas DataFrame,但是出现了各种错误。

这是代码:

from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
import pickle
import sklearn
import pandas as pd
import numpy as np

class Userdata(BaseModel):
  current_res_month_dec: Optional[int] = 0
  current_res_month_nov:  Optional[int] = 0


async def return_recurrent_user_predictions_gb(user_data: Userdata):

      empty_dataframe =  pd.DataFrame([Userdata(**{
      'current_res_month_dec': user_data.current_res_month_dec,
      'current_res_month_nov': user_data.current_res_month_nov})], ignore_index=True)

当我尝试在本地环境中通过/docs执行时,返回的是DataFrame

Response body
Download
{
  "0": {
    "0": [
      "current_res_month_dec",
      0
    ]
  },
  "1": {
    "0": [
      "current_res_month_nov",
      0
    ]
  }

但是,如果我试图使用这个DataFrame进行预测:

model_has_afternoon = pickle.load(open('./models/model_gbclf_prob_current_product_has_afternoon.pickle', 'rb'))
result_afternoon = model_has_afternoon.predict_proba(empty_dataframe)[:, 1]

我遇到了这个错误:

ValueError: setting an array element with a sequence.

我之前尝试过构建自己的DataFrame,并且预测应该与DataFrame一起工作。

1个回答

4

首先,您需要使用 Pydantic 的 dict() 方法将 Pydantic 模型转换为字典。请注意,已经发现其他方法,如 Python 的 dict() 函数和 .__dict__ 属性,是 Pydantic 的 dict() 方法的更快速的替代方法(详见这个答案)。不过,由于您正在使用 Pydantic 模型,最好使用 Pydantic 的 dict() 方法,然后将字典传递给用方括号括起来的 pandas.DataFrame();例如: pd.DataFrame([data.dict()])。正如这个答案中所述,当您需要传递的 dict 的键是且值是时,可以使用此方法。如果您需要指定不同的方向,您也可以使用 pandas.DataFrame.from_dict()。之后,您可以调用 model.predict(df) 来获取预测结果,就像这里这里演示的那样。

工作示例

from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
import pandas as pd

app = FastAPI()

class Userdata(BaseModel):
  col1: Optional[int] = 0
  col2:  Optional[int] = 0
  col3:  str = "foo"

@app.post('/submit')
def submit_data(data: Userdata):
    df = pd.DataFrame([data.dict()])
    # pred = model.predict(df)
    return "Success"

更多选项

如你所述,您希望使用 DataFrame 进行机器学习预测,需要注意到还有其他几个选项可用于传递数据到 predict()predict_proba() 函数,而不需要创建 DataFrame。这些选项包括:

model.predict([[data.col1, data.col2, data.col3]])

并且

model.predict([list(data.dict().values())])
请查看 this answer 以获得更多详细信息。如果您还需要以 JSON 格式响应客户端的 DataFrame,请参阅 此处

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,