Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 此时如何使用numpy进行矢量化+;(2x表示)嵌套循环?_Python_Loops_Numpy_Vectorization - Fatal编程技术网

Python 此时如何使用numpy进行矢量化+;(2x表示)嵌套循环?

Python 此时如何使用numpy进行矢量化+;(2x表示)嵌套循环?,python,loops,numpy,vectorization,Python,Loops,Numpy,Vectorization,我正在努力提高我正在研究的算法的处理速度。在尝试使用多处理池和映射在所有CPU核上有效地分配工作负载之前,如果可能的话,我想对这个循环进行矢量化 这里有一个例子 v = [1,2,3,4,5,6,7,8,9,10] w = [-3,-2,-1,0,1,2,3] u = sorted(w, reverse=True) i = 0 check = 0 while v[i] != v[-1]: if check == 0: for k in range(len(w)):

我正在努力提高我正在研究的算法的处理速度。在尝试使用多处理池和映射在所有CPU核上有效地分配工作负载之前,如果可能的话,我想对这个循环进行矢量化

这里有一个例子

v = [1,2,3,4,5,6,7,8,9,10]
w = [-3,-2,-1,0,1,2,3]
u = sorted(w, reverse=True)
i = 0
check = 0

while v[i] != v[-1]:
    if check == 0:
        for k in range(len(w)):
            if (v[i] < w[k] & v[i+1] >= w[k]) or (v[i] > w[k] & v[i+1] <= w[k]):
                do_somthing()
                check = 1
                break
    i = i+1
    if check == 1:
        for k in range(len(u)):
            if (v[i] <= u[k] & v[i-1] > u[k]) or (v[i] >= u[k] & v[i-1] < u[k]):
                do_something_else()
                check = 0
                break
    i = i+1     
v=[1,2,3,4,5,6,7,8,9,10]
w=[-3,-2,-1,0,1,2,3]
u=已排序(w,反向=真)
i=0
检查=0
而v[i]!=v[-1]:
如果检查==0:
对于范围内的k(len(w)):
如果(v[i]=w[k])或(v[i]>w[k]&v[i+1]=u[k]&v[i-1]

示例中的数组值是完全随机的。V至少包含2000个元素,而w的大小总是固定的。

下面是一个尝试。我观察到
块的第一个和第二个
中的条件是相同的,只有一个循环选择满足它的最低
w
,另一个循环选择最高的
w

你能检查一下下面的结果是否正确吗

import numpy as n

assert len(v) % 2 == 0
sg = w[-1] + 1 # create numbers that are safely out of range
sl = w[0] - 1  #

# in the original code, do_something is executed at most once for
# every pair of v depending on some conditions relating to w.
# the next lines find the smallest w that is still larger than v and
# similar things (in other words we are binning v with respect to w), 
# in a vectorised fashion, i.e. for all v in one go.
# using this info we can avoid the loop and for each pair of v just
# pick the first w if  any that would have left the two v through in
# the if inside the loop
# the difference between bin_inds_left and _right is whether the bins
# are l <= bin < r or l < bin <= r
bin_inds_left = np.digitize(v, w)
bin_inds_right = np.digitize(v, w, True)

# in your loops, various conditions are applied to v[i] and v[i+1]
# or similarly, in vectorised code this translates to slice offsets
# the two following lines create the logical masks corresponding to
# the conditions in the left and right halves of the if statement
# in the first loop (IIRC they are swapped in the second loop)
# these masks are True if there is any permissible w and otherwise 
# False
mask_l = bin_inds_left[1::2] > bin_inds_left[::2]
mask_r = bin_inds_right[1::2] < bin_inds_right[::2]

mask = mask_l | mask_r

# for each pair find the smallest w that satisfies the left condition
k1 = bin_inds_left[::2][mask]
k1[~mask_l[mask]] = sg # this marks places where there is no such w

# and in the right condition
k2 = bin_inds_right[1::2][mask]
k2[~mask_r[mask]] = sg

# since it is or gated the first (smaller) of the two w's wins
kminw = np.minimum(k1, k2)

# same for the second loop
k1 = bin_inds_left[1::2][mask]
k1[~mask_l[mask]] = sl

k2 = bin_inds_right[::2][mask]
k2[~mask_r[mask]] = sl

# but since u is upside-down compared to w and we do all caluclations
# in w coordinates we must take the maximum
# and in the very last step we translate to u coordinates
kminu = len(w) - 1 - np.maximum(k1, k2)

do_something(kminw, 2*np.where(mask)[0])
do_something_else(kminu, 1 + 2*np.where(mask)[0])
将numpy作为n导入
断言len(v)%2==0
sg=w[-1]+1#创建安全超出范围的数字
sl=w[0]-1#
#在原始代码中,do_something最多执行一次
#每对v取决于与w有关的一些条件。
#下一行找到仍然大于v和的最小w
#类似的事情(换句话说,我们将v与w结合起来),
#以矢量化方式,即一次完成所有v。
#使用此信息,我们可以避免循环,对于每对v
#选择第一个w(如果有的话),它会留下两个v
#循环中的if
#左侧和右侧垃圾桶的区别在于垃圾桶

#l是否排序为
w
,使得
u
w
是镜像?是的,w排序为最低值->最高值。为什么不将此函数设置为接受
ndarray
v
w
参数的函数。然后用
numba.jit
编译函数。对于不依赖本机CPython数据类型的特殊循环操作,
numba.jit
几乎总是您的最佳选择,并且通常比矢量化的numpy版本更快,我同意Paul建议的矢量化版本比我的“noob”代码更难阅读,但我认为这是因为我的编码技巧。我只是对什么是numba以及在什么情况下应该使用它有一个“总体概念”。你能提供一些有用的链接吗?我只需要将@jit装饰器放在函数定义(def)之前,让神奇的事情发生?numba.jit与Paul提出的矢量化解决方案一起工作吗?感谢您的快速回答。我正在从头开始重写整个算法,所以我仍然需要重写do_something()和do_something_else()函数以及其他很多东西。我会尽快告诉你的,再次谢谢你!我得到了两次相同的“TypeError:只有长度为1的数组才能转换为Python标量”。第一次kminw=np.min(k1,k2),第二次kminu=len(w)-1-np.max(k1,k2)。我正在阅读有关您使用的模块和函数的numpy文档,但很明显我没有您熟练。你能逐行解释一下你的代码是什么吗?因为真诚地说,我对它几乎没有任何怀疑。再次感谢。哦,使用了错误的
max
,(有
max
max
)对此表示抱歉。我会看看我能做些什么来更好地解释。