【问题标题】:How to append result of multiprocessing Pool based on index from input list in Python?如何根据 Python 输入列表中的索引附加多处理池的结果?
【发布时间】:2017-03-23 23:04:33
【问题描述】:

总的来说,我的脚本正在输入:

  1. 地址查询查询
  2. 纬度/经度坐标

我需要做的是调用地理编码 API 来获取查询列表中每个地址的响应,解析 XML 响应以获取我需要的信息,并检查新返回的点是否与文件中的点匹配。

在我尝试使用 Python 中的多处理功能来帮助加快任务之前,我的设置工作正常。

使用多处理时,我可以获得最终结果,但出现的问题是处理的随机顺序,我收到的多处理结果与正确的输入查询不匹配。

例如“123 Main Street”结果附加到“431 Main Street”,“431 Main Street”结果附加到“123 Main Street”

我的问题是: 如何让多处理结果追加到正确的查询,而不是根据处理顺序追加?

我正在使用 Pandas 数据框来跟踪数据。

部分相关:

    def apiRequest(query):
        url = 'URL goes here'
        parameters = {'q':query,'other parameters are here'}
        request = requests.get(url,params=parameters) 
        result = ET.fromstring(request.text)
    return(result)

    results = pool.map(apiRequest,queryList)

    #This is where I append the result where order is based on multiprocessing result list
    i=0
    for result in results:
        df.loc[result[i],'Result Text'] = result
        i=i+1  

编辑:链接线程非常相似,但不完全是我需要的。我从下面的评论中发现,多处理列表确实按输入列表的顺序返回,而不是按处理顺序返回。有了这些信息,我意识到我只需要参考响应的索引。我使用附加线程中的 enumerate 函数做到了这一点,所以它很有帮助。

另一个不相关的问题现在.. 似乎多处理不起作用。花费的时间是以前的两倍。解决一个问题,另一个问题出现了!

感谢您的帮助!

【问题讨论】:

标签: python pandas indexing multiprocessing geocoding


【解决方案1】:

pool.map 的结果按照与输入数据匹配的顺序返回。请考虑以下示例。

from multiprocessing import Pool
import time, random

def f(x):
    t = random.random() # sleep for a random time to mix up the results
    time.sleep(t)
    print(x)
    return (t, str(x))

if __name__ == '__main__':
    p = Pool(3) # 3 worker threads
    data = range(10)
    print(p.map(f, data))

结果:

1
2
4
5
0
3
7
6
8
9
[(0.8381880180345248, '0'), (0.3361198414214449, '1'), (0.48073509426290906, '2'), (0.5767279178958461, '3'), (0.14369537417791844, '4'), (0.1914456539782432, '5'), (0.7090097213160568, '6'), (0.624456052752851, '7'), (0.79705548172654, '8'), (0.9956179715628799, '9')]

请注意,即使结果由于随机延迟而被乱序计算,但结果列表的顺序是正确的。

我怀疑问题出在你处理结果的方式上。

#This is where I append the result where order is based on multiprocessing result list
i=0
for result in results:
    df.loc[result[i],'Result Text'] = result
    i=i+1  

您已经在遍历results,那为什么还要用递增的数字索引结果?

听起来你应该引用来自queryList的匹配输入数据,例如:

for query, result in zip(queryList, results):
    # this is probably not quite right, but basically do something
    # with query and result
    df.loc[query,'Result Text'] = result

【讨论】:

  • 谢谢你,我对结果有误解。这绝对是我处理响应的方式。我相信我需要做的是引用查询的索引而不是查询本身(因为列表中可能有多个相同的查询)。您的回复加上上面链接的主题应该可以帮助我解决这个问题!
  • @SilentSun 没问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 2013-09-28
  • 2014-08-25
  • 1970-01-01
  • 2023-02-23
  • 2021-12-12
  • 1970-01-01
相关资源
最近更新 更多