同时应用于多行

2024-04-25 20:19:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧,我想调用一个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行,自己创建批处理,然后再次迭代以在新列上添加返回值?你知道吗


Tags: 数据textimportapiidjsondfdata
1条回答
网友
1楼 · 发布于 2024-04-25 20:19:21

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

df.to_dict('records')

然后你只需要把它分成100块:

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

最后,您可以使用一个带有requests库的HTTP会话:

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

然后在call_api()内部执行session.post(...)。这比每次建立一个新连接更有效。你知道吗

相关问题 更多 >