Skip to main content
 首页 » 编程设计

python之同时应用于多行

2024年09月03日9xing901022

我有一个 Pandas 数据框,我想调用一个 API 并从该数据框传递一些参数。然后我从 API 获取结果并从中创建一个新列。这是我的工作代码:

import http.client, urllib.request, urllib.parse, urllib.error, base64 
import pandas as pd 
import json 
 
headers = { 
    # Request headers 
    'Content-Type': 'application/json', 
    'Ocp-Apim-Subscription-Key': 'my-api-key-goes-here', 
} 
 
params = urllib.parse.urlencode({ 
}) 
 
df = pd.read_csv('mydata.csv',names=['id','text']) 
 
def call_api(row): 
    try: 
        body = { 
          "documents": [ 
                { 
                    "language": "en", 
                    "id": row['id'], 
                    "text": row['text'] 
                } 
            ] 
        } 
        conn = http.client.HTTPSConnection('api-url') 
        conn.request("POST", "api-endpoint" % params, str(body), headers) 
        response = conn.getresponse() 
        data = response.read() 
        data = json.loads(data) 
        return data['documents'][0]['score'] 
        conn.close() 
    except Exception as e: 
        print("[Errno {0}] {1}".format(e.errno, e.strerror)) 
 
 
df['score'] = df.apply(call_api,axis=1) 

上面的效果很好。但是,我对可以执行的 api 请求的数量有限制,API 允许我在同一请求中发送最多 100 个文档,方法是在 body['documents'] 列表中添加更多文档。

返回的数据遵循这个模式:

{ 
  "documents": [ 
    { 
      "score": 0.92, 
      "id": "1" 
    }, 
    { 
      "score": 0.85, 
      "id": "2" 
    }, 
    { 
      "score": 0.34, 
      "id": "3" 
    } 
  ], 
  "errors": null 
} 

因此,我正在寻找的是不是逐行应用相同的 api 调用,而是每次以 100 行为一组。有什么方法可以在 Pandas 中执行此操作,还是我应该迭代数据框行,自己创建批处理,然后再次迭代以将返回值添加到新列?

请您参考如下方法:

DataFrame.apply() 很慢;我们可以做得更好。这将一次性创建“文档”字典列表:

df.to_dict('records') 

然后您需要做的就是将其分成 100 个 block :

start = 0 
while start < len(df): 
    documents = df.iloc[start:start+100].to_dict('records') 
    call_api(documents) 
    start += 100 

最后,您可以将单个 HTTP session 与 requests 库一起使用:

import requests 
session = requests.Session() 
call_api(session, documents) 

然后在 call_api() 中执行 session.post(...)。这比每次都建立一个新连接更有效率。