You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

从OpenAI API获取数据填充Pandas DataFrame时部分字段为空的解决方法

从OpenAI API获取数据填充Pandas DataFrame时部分字段为空的解决方法

看起来你遇到的问题挺典型的——循环调用OpenAI API补全信息时,部分字段(比如沃尔玛的CEO相关内容)会返回空值,但单独请求却能拿到有效数据对吧?我来帮你分析下可能的原因,再给你具体的解决办法:

问题根源分析

  1. 提示词约束不够明确:你原来的prompt只要求按指定键返回JSON,但没明确说"哪怕信息不确定也不能留空,必须填'未知'这类占位符",GPT模型有时候会偷懒,遇到拿不准的信息直接返回空字符串。
  2. 请求频率过高导致响应质量下降:循环里连续发请求,间隔太短的话,OpenAI的模型可能会简化响应,或者返回不完整的结果(尤其是配额紧张的时候)。
  3. 缺少校验和重试机制:没检查返回结果的字段是否为空,也没在拿到空值时重新请求,导致空数据直接被存入DataFrame。

具体解决步骤(附代码修改)

1. 优化提示词,明确强制填充规则

把你的提示词改得更严苛,明确要求所有字段必须有值,未知信息用"未知"代替,绝对不能留空:

user_prompt = f"""
请严格按照以下指定的JSON格式,返回{company_name}的相关信息:
必须包含所有以下键:{', '.join(json_format)}
**注意:任何信息无法获取或不确定时,必须填充为"未知",绝对不能留空字符串!**

返回的内容只能是合法的单个JSON对象,不能有多余的文字或格式。
"""

2. 增加重试机制 + 请求间隔

封装API请求逻辑成函数,加入重试机制——如果返回的字段有空值,自动重新请求;同时在循环和重试中加入时间间隔,避免请求太密集:

完整修改后的代码

import time
import json
import openai
import pandas as pd

# 初始化OpenAI客户端(记得替换成你的API密钥)
client = openai.OpenAI(api_key="your-api-key-here")

sample_df = pd.DataFrame({
    'Rank': [1, 2, 3],
    'Company': ['Walmart', 'Amazon', 'State Grid'],
    'Revenue': ['$648,125', '$574,785', '$545,947.5'],
    'Profit': ['6%', '11.8%', '3%'],
    'Assets': ['$15,511', '$30,425', '$9,204.3'],
    'Market Value': ['32.8%', '-', '12.4%']
})

json_format = ["Company", "Country of Origin", "Industry", "CEO name", "Bachelor Degree", 
               "University Attended for Bachelor Degree", "MBA", "University for MBA"]

def get_company_info(company_name, max_retries=3):
    retry_count = 0
    while retry_count < max_retries:
        try:
            # 明确约束的提示词
            user_prompt = f"""
请严格按照以下指定的JSON格式,返回{company_name}的相关信息:
必须包含所有以下键:{', '.join(json_format)}
**注意:任何信息无法获取或不确定时,必须填充为"未知",绝对不能留空字符串!**

返回的内容只能是合法的单个JSON对象,不能有多余的文字或格式。
"""
            completion = client.chat.completions.create(
                model="gpt-3.5-turbo-0125",
                response_format={"type": "json_object"},
                messages=[
                    {"role": "system", "content": "你是专业的企业信息查询助手,必须严格按照要求返回合法JSON,所有字段不能为空,未知信息填'未知'。"},
                    {"role": "user", "content": user_prompt}
                ]    
            )
            json_data = json.loads(completion.choices[0].message.content)
            # 检查所有字段是否都不为空
            all_filled = all(json_data.get(key, "") != "" for key in json_format)
            if all_filled:
                return json_data
            else:
                print(f"{company_name}存在空字段,正在重试第{retry_count+1}次...")
                retry_count += 1
                time.sleep(2)
        except Exception as e:
            print(f"请求{company_name}时出错:{str(e)},正在重试...")
            retry_count += 1
            time.sleep(2)
    # 多次重试失败后,用"未知"填充所有字段
    fallback_data = {key: "未知" for key in json_format}
    fallback_data["Company"] = company_name
    return fallback_data

# 初始化结果DataFrame
df_json = pd.DataFrame(columns=json_format)

# 循环处理每个公司
for _, row in sample_df.iterrows():
    company_name = row['Company']
    print(f"正在获取{company_name}的信息...")
    company_info = get_company_info(company_name)
    new_row = pd.DataFrame([company_info])
    df_json = pd.concat([df_json, new_row], ignore_index=True)
    # 增加请求间隔,避免过于密集
    time.sleep(1)

print(df_json.head())

额外优化建议

  • 如果你对数据准确性要求高,可以换成gpt-4模型,它的信息覆盖度和响应质量比gpt-3.5-turbo更高,只是成本会稍高。
  • 可以考虑使用OpenAI的批量API处理请求,比循环单条请求更高效,也能避免频率限制带来的问题(需要按官方要求准备批量请求文件)。
  • 定期检查你的OpenAI API配额,如果接近上限,也会导致响应质量下降,甚至返回不完整数据。

备注:内容来源于stack exchange,提问作者Faizul Zuraimi

火山引擎 最新活动