用于API调用的最快方式循环Pandas DataFrame

时间:2017-10-17 21:07:22

标签: python pandas python-requests

我的目标是为Pandas DataFrame中的每一行调用API,其中包含响应JSON中的字符串List,并创建一个每个响应一行的新DataFrame。我的代码基本上是这样的:

i = 0
new_df = pandas.DataFrame(columns = ['a','b','c','d'])
for index,row in df.iterrows():
    url = 'http://myAPI/'
    d = '{"SomeJSONData:"' + row['data'] + '}'
    j = json.loads(d)
    response = requests.post(url,json = j)

    data = response.json()
    for new_data in data['c']:
        new_df.loc[i] = [row['a'],row['b'],row['c'],new_data]
        i += 1

这很好用,但是我正在进行大约5500次API调用并将大约6500行写入新的DataFrame,因此需要一段时间,可能需要10分钟。我想知道是否有人知道如何加快这个速度?我不太熟悉在Python中运行并行for循环,这可以在保持线程安全的同时完成吗?

1 个答案:

答案 0 :(得分:4)

也许这些方面的东西?这样您就不会创建一个全新的数据帧,只需要声明一次URL,并且您正在利用pandas列操作比逐行的更快的事实。

url = 'http://myAPI/'

def request_function(j):
    return requests.post(url,json = json.loads(j))['c'] 

df['j']= '{"SomeJsonData:"' + df['data'] + '}'
df['new_data'] = df['j'].apply(request_function)

现在要证明在这种情况下使用apply(字符串数据)确实要快得多,这是一个简单的测试:

import numpy as np
import pandas as pd
import time

def func(text):
    return text + ' is processed'


def test_one():
    data =pd.DataFrame(columns = ['text'], index = np.arange(0, 100000))
    data['text'] = 'text'

    start = time.time()
    data['text'] = data['text'].apply(func)
    print(time.time() - start)


def test_two():
    data =pd.DataFrame(columns = ['text'], index = np.arange(0, 100000))
    data['text'] = 'text'

    start = time.time()

    for index, row in data.iterrows():
        data.loc[index, 'text'] = row['text'] + ' is processed'

    print(time.time() - start)
  

数据帧上字符串操作的结果。

     

test_one(使用申请):0.023002147674560547

     

test_two(使用iterrows):18.912891149520874

基本上,通过使用添加两列并应用的内置pandas操作,您应该有一些更快的结果,您的响应时间确实受到API响应时间的限制。如果结果仍然太慢,您可能会考虑编写将结果保存到列表的异步函数。然后你send.apply那个异步函数。