小编mpt*_*ion的帖子

Python请求 - 线程/进程与IO

我通过HTTP连接到本地服务器(OSRM)以提交路由并返回驱动时间.我注意到I/O比线程慢,因为似乎计算的等待时间小于发送请求和处理JSON输出所花费的时间(我认为当服务器需要一些时间时I/O更好处理你的请求 - >你不希望它被阻止,因为你必须等待,这不是我的情况).线程受全局解释器锁的影响,因此我看来(以及下面的证据)我最快的选择是使用多处理.

多处理的问题是它太快以至于耗尽了我的套接字并且我收到了一个错误(请求每次都发出一个新的连接).我可以(在串行中)使用requests.Sessions()对象来保持连接活动,但是我不能让它并行工作(每个进程都有它自己的会话).

我目前最接近的代码就是这个多处理代码:

conn_pool = HTTPConnectionPool(host='127.0.0.1', port=5005, maxsize=cpu_count())

def ReqOsrm(url_input):
    ul, qid = url_input      
    try:
        response = conn_pool.request('GET', ul)
        json_geocode = json.loads(response.data.decode('utf-8'))
        status = int(json_geocode['status'])
        if status == 200:
            tot_time_s = json_geocode['route_summary']['total_time']
            tot_dist_m = json_geocode['route_summary']['total_distance']
            used_from, used_to = json_geocode['via_points']
            out = [qid, status, tot_time_s, tot_dist_m, used_from[0], used_from[1], used_to[0], used_to[1]]
            return out
        else:
            print("Done but no route: %d %s" % (qid, req_url))
            return [qid, 999, 0, 0, 0, 0, 0, 0]
    except Exception as err:
        print("%s: %d %s" % …
Run Code Online (Sandbox Code Playgroud)

python concurrency multithreading asynchronous python-multiprocessing

14
推荐指数
2
解决办法
2431
查看次数

在列表中交叉字符串的快速方法

如果有这样的列表:

shops=['A','B','C','D']
Run Code Online (Sandbox Code Playgroud)

并且想要创建以下新列表(我将每个元素彼此交叉并创建一个字符串,其中第一部分在第二部分之前是字母数字):

['A-B', 'A-C', 'A-D']

['A-B', 'B-C', 'B-D']

['A-C', 'B-C', 'C-D']

['A-D', 'B-D', 'C-D']
Run Code Online (Sandbox Code Playgroud)

我有这样的事情:

for a in shops:
    cons = []
    for b in shops:
        if a!=b:
            con = [a,b]
            con = sorted(con, key=lambda x: float(x))
            cons.append(con[0]+'-'+con[1])
    print(cons)
Run Code Online (Sandbox Code Playgroud)

但是,这对于大型列表来说相当慢(例如1000,其中我有1000*999*0.5输出).我一直在寻找一种更有效的方法吗?

我可以使用if-else子句进行排序,例如

for a in shops:
    cons = []
    for b in shops:
        if a<b:
            cons.append(a+"-"+b)
        elif a>b:
            cons.append(b+"-"+a)
    print(cons)
Run Code Online (Sandbox Code Playgroud)

哪个,我还没有定时 - 但我认为主要的减速是双循环

python list concatenation

12
推荐指数
1
解决办法
618
查看次数

Python快速计算很多距离

我有一个36,742点的输入,这意味着如果我想计算距离矩阵的下三角形(使用vincenty近似),我需要生成36,742*36,741*0.5 = 1,349,974,563距离.

我想保持彼此相距50公里的对组合.我目前的设置如下

shops= [[id,lat,lon]...]

def lower_triangle_mat(points):
    for i in range(len(shops)-1):
        for j in range(i+1,len(shops)):
            yield [shops[i],shops[j]]

def return_stores_cutoff(points,cutoff_km=0):
    below_cut = []
    counter = 0
    for x in lower_triangle_mat(points):
        dist_km = vincenty(x[0][1:3],x[1][1:3]).km
        counter += 1
        if counter % 1000000 == 0:
            print("%d out of %d" % (counter,(len(shops)*len(shops)-1*0.5)))
        if dist_km <= cutoff_km:
            below_cut.append([x[0][0],x[1][0],dist_km])
    return below_cut

start = time.clock()
stores = return_stores_cutoff(points=shops,cutoff_km=50)
print(time.clock() - start)
Run Code Online (Sandbox Code Playgroud)

这显然需要数小时和数小时.我想到的一些可能性:

  • 使用numpy来矢量化这些计算而不是循环
  • 使用某种哈希来快速粗略(100公里内的所有商店),然后只计算这些商店之间的准确距离
  • 而不是将点存储在列表中使用类似四叉树的东西,但我认为这只能帮助关闭点的排名而不是实际距离 - >所以我想某种地理数据库
  • 我可以明显地尝试半正矢或项目,并利用欧氏距离,但我很感兴趣,使用最准确的测量可能 …

python numpy distance haversine geohashing

7
推荐指数
1
解决办法
2336
查看次数