【问题标题】:Faster way to iterate over dataframe?更快地迭代数据框的方法?
【发布时间】:2022-01-16 09:07:09
【问题描述】:

我有一个数据框,其中每一行都是一条记录,我需要在发布请求的正文中发送每条记录。现在我正在遍历数据框来完成这个。我受到每条记录必须单独发布这一事实的限制。有没有更快的方法来做到这一点?

【问题讨论】:

  • 这取决于您数据的结构/格式,以及服务器是否接受批量上传。如果您可以向我们提供这些信息,或许我们可以为您提供帮助。
  • 数据以嵌套结构的 JSON 格式发送。不幸的是,服务器不接受批量上传,这让我很困惑,因为普通用户可能需要频繁更新数万条记录。
  • 请显示尝试的循环和所需的输出。实现目标的方法可能有很多。

标签: python pandas loops time space


【解决方案1】:

迭代数据框不是这里的问题。问题是您必须等待服务器响应您的每个请求。与迭代数据帧所需的 CPU 时间相比,网络请求需要 eons。换句话说,您的程序受 I/O 限制,而不是 CPU 限制。

加快速度的一种方法是使用协程。假设您必须提出 1000 个请求。不是触发一个请求,而是等待响应,然后触发下一个请求等等,而是一次触发 1000 个请求并告诉 Python 等待,直到收到所有 1000 个响应。

由于您没有提供任何代码,这里有一个小程序来说明这一点:

import aiohttp
import asyncio
import numpy as np
import time

from typing import List

async def send_single_request(session: aiohttp.ClientSession, url: str):
    async with session.get(url) as response:
        return await response.json()

async def send_all_requests(urls: List[str]):
    async with aiohttp.ClientSession() as session:
        # Make 1 coroutine for each request
        coroutines = [send_single_request(session, url) for url in urls]
        # Wait until all coroutines have finished
        return await asyncio.gather(*coroutines)

# We will make 10 requests to httpbin.org. Each request will take at least d
# seconds. If you were to fire them sequentially, they would have taken at least
# delays.sum() seconds to complete.
np.random.seed(42)
delays = np.random.randint(0, 5, 10)
urls = [f"https://httpbin.org/delay/{d}" for d in delays]

# Instead, we will fire all 10 requests at once, then wait until all 10 have
# finished.
t1 = time.time()
result = asyncio.run(send_all_requests(urls))
t2 = time.time()

print(f"Expected time: {delays.sum()} seconds")
print(f"Actual time: {t2 - t1:.2f} seconds")

输出:

Expected time: 28 seconds
Actual time: 4.57 seconds

您必须阅读一些关于协程及其工作原理的内容,但在大多数情况下,它们对于您的用例来说并不太复杂。这有几个注意事项:

  1. 您的所有请求都必须相互独立。
  2. 服务器上的速率限制必须足以处理您的工作负载。例如,如果它将您限制为每分钟 2 个请求,那么除了升级到不同的服务层之外别无他法。

【讨论】:

  • 谢谢,这很有帮助。
猜你喜欢
  • 2019-10-09
  • 2020-06-10
  • 2018-03-07
  • 2016-08-21
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
相关资源
最近更新 更多