Применить в несколько рядов одновременно - PullRequest
0 голосов
/ 20 октября 2018

У меня есть фрейм данных 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, или я должен выполнить итерацию по строкам данных, создать пакеты самостоятельно, а затем повторить итерацию, чтобы добавить возвращаемые значения в новый столбец?

1 Ответ

0 голосов
/ 20 октября 2018

DataFrame.apply() медленно;мы можем сделать лучшеЭто создаст список «документов» за один раз:

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

Наконец,Вы можете использовать один сеанс HTTP с библиотекой requests:

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

Затем внутри call_api() вы делаете session.post(...).Это эффективнее, чем каждый раз устанавливать новое соединение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...