我的目标是为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循环,这可以在保持线程安全的同时完成吗?
答案 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那个异步函数。