DataFrame 结构化数据提取¶
这个演示展示了如何从原始文本中提取表格数据框。
这直接受到了jxnl在这里的数据框示例的启发:https://github.com/jxnl/openai_function_call/blob/main/auto_dataframe.py。
我们展示了不同复杂程度的示例,都由OpenAI函数API支持:
- (更多代码)如何使用我们的OpenAIPydanticProgram自己构建提取器
- (更少代码)使用我们的开箱即用的
DFFullProgram
和DFRowsProgram
对象
自己构建一个DF提取器(使用OpenAIPydanticProgram)¶
我们的OpenAIPydanticProgram是围绕OpenAI LLM的一个包装器,支持函数调用 - 它将以Pydantic对象的形式返回结构化输出。
我们导入了DataFrame
和DataFrameRowsOnly
对象。
要创建一个输出提取器,你只需要 1) 指定相关的Pydantic对象,和 2) 添加正确的提示。
如果您在colab上打开这个笔记本,您可能需要安装LlamaIndex 🦙。
In [ ]:
Copied!
%pip install llama-index-llms-openai
%pip install llama-index-program-openai
%pip install llama-index-llms-openai
%pip install llama-index-program-openai
In [ ]:
Copied!
!pip install llama-index
!pip install llama-index
In [ ]:
Copied!
from llama_index.program.openai import OpenAIPydanticProgram
from llama_index.core.program import (
DFFullProgram,
DataFrame,
DataFrameRowsOnly,
)
from llama_index.llms.openai import OpenAI
from llama_index.program.openai import OpenAIPydanticProgram
from llama_index.core.program import (
DFFullProgram,
DataFrame,
DataFrameRowsOnly,
)
from llama_index.llms.openai import OpenAI
In [ ]:
Copied!
program = OpenAIPydanticProgram.from_defaults(
output_cls=DataFrame,
llm=OpenAI(temperature=0, model="gpt-4-0613"),
prompt_template_str=(
"Please extract the following query into a structured data according"
" to: {input_str}.Please extract both the set of column names and a"
" set of rows."
),
verbose=True,
)
program = OpenAIPydanticProgram.from_defaults(
output_cls=DataFrame,
llm=OpenAI(temperature=0, model="gpt-4-0613"),
prompt_template_str=(
"Please extract the following query into a structured data according"
" to: {input_str}.Please extract both the set of column names and a"
" set of rows."
),
verbose=True,
)
In [ ]:
Copied!
# 注意:测试示例取自jxnl的存储库response_obj = program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他的名字是迈克,他今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽的名字,她今年35岁。她住在芝加哥。""")response_obj
# 注意:测试示例取自jxnl的存储库response_obj = program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他的名字是迈克,他今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽的名字,她今年35岁。她住在芝加哥。""")response_obj
Function call: DataFrame with args: { "columns": [ { "column_name": "Name", "column_desc": "Name of the person" }, { "column_name": "Age", "column_desc": "Age of the person" }, { "column_name": "City", "column_desc": "City where the person lives" }, { "column_name": "Hobby", "column_desc": "What the person likes to do" } ], "rows": [ { "row_values": ["John", 25, "New York", "play basketball"] }, { "row_values": ["Mike", 30, "San Francisco", "play baseball"] }, { "row_values": ["Sarah", 20, "Los Angeles", "play tennis"] }, { "row_values": ["Mary", 35, "Chicago", "play tennis"] } ] }
Out[ ]:
DataFrame(description=None, columns=[DataFrameColumn(column_name='Name', column_desc='Name of the person'), DataFrameColumn(column_name='Age', column_desc='Age of the person'), DataFrameColumn(column_name='City', column_desc='City where the person lives'), DataFrameColumn(column_name='Hobby', column_desc='What the person likes to do')], rows=[DataFrameRow(row_values=['John', 25, 'New York', 'play basketball']), DataFrameRow(row_values=['Mike', 30, 'San Francisco', 'play baseball']), DataFrameRow(row_values=['Sarah', 20, 'Los Angeles', 'play tennis']), DataFrameRow(row_values=['Mary', 35, 'Chicago', 'play tennis'])])
In [ ]:
Copied!
program = OpenAIPydanticProgram.from_defaults(
output_cls=DataFrameRowsOnly,
llm=OpenAI(temperature=0, model="gpt-4-0613"),
prompt_template_str=(
"Please extract the following text into a structured data:"
" {input_str}. The column names are the following: ['Name', 'Age',"
" 'City', 'Favorite Sport']. Do not specify additional parameters that"
" are not in the function schema. "
),
verbose=True,
)
program = OpenAIPydanticProgram.from_defaults(
output_cls=DataFrameRowsOnly,
llm=OpenAI(temperature=0, model="gpt-4-0613"),
prompt_template_str=(
"Please extract the following text into a structured data:"
" {input_str}. The column names are the following: ['Name', 'Age',"
" 'City', 'Favorite Sport']. Do not specify additional parameters that"
" are not in the function schema. "
),
verbose=True,
)
In [ ]:
Copied!
program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他叫迈克,今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽的名字,她今年35岁。她住在芝加哥。""")
program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他叫迈克,今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽的名字,她今年35岁。她住在芝加哥。""")
Function call: DataFrameRowsOnly with args: { "rows": [ { "row_values": ["John", 25, "New York", "basketball"] }, { "row_values": ["Mike", 30, "San Francisco", "baseball"] }, { "row_values": ["Sarah", 20, "Los Angeles", "tennis"] }, { "row_values": ["Mary", 35, "Chicago", ""] } ] }
Out[ ]:
DataFrameRowsOnly(rows=[DataFrameRow(row_values=['John', 25, 'New York', 'basketball']), DataFrameRow(row_values=['Mike', 30, 'San Francisco', 'baseball']), DataFrameRow(row_values=['Sarah', 20, 'Los Angeles', 'tennis']), DataFrameRow(row_values=['Mary', 35, 'Chicago', ''])])
使用我们的DataFrame程序¶
我们为DFFullProgram
和DFRowsProgram
提供了便利的包装器。这允许比通过OpenAIPydanticProgram
指定所有细节更简单的对象创建接口。
In [ ]:
Copied!
from llama_index.program.openai import OpenAIPydanticProgramfrom llama_index.core.program import DFFullProgram, DFRowsProgramimport pandas as pd# 初始化空的数据框df = pd.DataFrame( { "Name": pd.Series(dtype="str"), "Age": pd.Series(dtype="int"), "City": pd.Series(dtype="str"), "Favorite Sport": pd.Series(dtype="str"), })# 初始化程序,使用现有的数据框作为模式df_rows_program = DFRowsProgram.from_defaults( pydantic_program_cls=OpenAIPydanticProgram, df=df)
from llama_index.program.openai import OpenAIPydanticProgramfrom llama_index.core.program import DFFullProgram, DFRowsProgramimport pandas as pd# 初始化空的数据框df = pd.DataFrame( { "Name": pd.Series(dtype="str"), "Age": pd.Series(dtype="int"), "City": pd.Series(dtype="str"), "Favorite Sport": pd.Series(dtype="str"), })# 初始化程序,使用现有的数据框作为模式df_rows_program = DFRowsProgram.from_defaults( pydantic_program_cls=OpenAIPydanticProgram, df=df)
In [ ]:
Copied!
# 使用现有的df作为模式解析文本result_obj = df_rows_program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他叫迈克,他今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽叫玛丽,她今年35岁。她住在芝加哥。""")
# 使用现有的df作为模式解析文本result_obj = df_rows_program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他叫迈克,他今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽叫玛丽,她今年35岁。她住在芝加哥。""")
In [ ]:
Copied!
result_obj.to_df(existing_df=df)
result_obj.to_df(existing_df=df)
/Users/jerryliu/Programming/gpt_index/llama_index/program/predefined/df.py:65: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead. return existing_df.append(new_df, ignore_index=True)
Out[ ]:
Name | Age | City | Favorite Sport | |
---|---|---|---|---|
0 | John | 25 | New York | Basketball |
1 | Mike | 30 | San Francisco | Baseball |
2 | Sarah | 20 | Los Angeles | Tennis |
3 | Mary | 35 | Chicago |
In [ ]:
Copied!
# 初始化程序,可以进行联合模式提取和结构化数据提取df_full_program = DFFullProgram.from_defaults( pydantic_program_cls=OpenAIPydanticProgram,)
# 初始化程序,可以进行联合模式提取和结构化数据提取df_full_program = DFFullProgram.from_defaults( pydantic_program_cls=OpenAIPydanticProgram,)
In [ ]:
Copied!
result_obj = df_full_program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他叫迈克,他今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽叫玛丽,她今年35岁。她住在芝加哥。""")
result_obj = df_full_program( input_str="""我的名字是约翰,我今年25岁。我住在纽约,喜欢打篮球。他叫迈克,他今年30岁。他住在旧金山,喜欢打棒球。莎拉今年20岁,住在洛杉矶。她喜欢打网球。玛丽叫玛丽,她今年35岁。她住在芝加哥。""")
In [ ]:
Copied!
result_obj.to_df()
result_obj.to_df()
Out[ ]:
Name | Age | Location | Hobby | |
---|---|---|---|---|
0 | John | 25 | New York | Basketball |
1 | Mike | 30 | San Francisco | Baseball |
2 | Sarah | 20 | Los Angeles | Tennis |
3 | Mary | 35 | Chicago |
In [ ]:
Copied!
# 初始化空的数据框df = pd.DataFrame( { "City": pd.Series(dtype="str"), "State": pd.Series(dtype="str"), "Population": pd.Series(dtype="int"), })# 初始化程序,使用现有的数据框作为模式df_rows_program = DFRowsProgram.from_defaults( pydantic_program_cls=OpenAIPydanticProgram, df=df)
# 初始化空的数据框df = pd.DataFrame( { "City": pd.Series(dtype="str"), "State": pd.Series(dtype="str"), "Population": pd.Series(dtype="int"), })# 初始化程序,使用现有的数据框作为模式df_rows_program = DFRowsProgram.from_defaults( pydantic_program_cls=OpenAIPydanticProgram, df=df)
In [ ]:
Copied!
input_text = """旧金山位于加利福尼亚州,人口为800,000。纽约市是美国人口最多的城市。2020年,纽约市的人口为8,804,190,分布在300.46平方英里(778.2平方公里)的土地上,是美国人口密度最大的主要城市。纽约市位于纽约州。波士顿(美国:/ˈbɔːstən/),[8]正式名称为波士顿市,是马萨诸塞州的首府和最大城市,也是美国东北部新英格兰地区的文化和金融中心。该市边界包括约48.4平方英里(125平方公里)的区域,2020年人口为675,647。[4]"""# 解析文本,使用现有的df作为模式result_obj = df_rows_program(input_str=input_text)
input_text = """旧金山位于加利福尼亚州,人口为800,000。纽约市是美国人口最多的城市。2020年,纽约市的人口为8,804,190,分布在300.46平方英里(778.2平方公里)的土地上,是美国人口密度最大的主要城市。纽约市位于纽约州。波士顿(美国:/ˈbɔːstən/),[8]正式名称为波士顿市,是马萨诸塞州的首府和最大城市,也是美国东北部新英格兰地区的文化和金融中心。该市边界包括约48.4平方英里(125平方公里)的区域,2020年人口为675,647。[4]"""# 解析文本,使用现有的df作为模式result_obj = df_rows_program(input_str=input_text)
In [ ]:
Copied!
new_df = result_obj.to_df(existing_df=df)
new_df
new_df = result_obj.to_df(existing_df=df)
new_df
/Users/jerryliu/Programming/gpt_index/llama_index/program/predefined/df.py:65: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead. return existing_df.append(new_df, ignore_index=True)
Out[ ]:
City | State | Population | |
---|---|---|---|
0 | San Francisco | California | 800000 |
1 | New York City | New York | 8804190 |
2 | Boston | Massachusetts | 675647 |