替换Python中的深循环

替换Python中的深循环,python,numpy,while-loop,Python,Numpy,While Loop,不幸的是,我的Python代码中经常有while循环,这会导致我的程序速度显著降低 以下是while循环(shape=(10001000,3))的示例: i=0 j=0 而我

不幸的是,我的Python代码中经常有while循环,这会导致我的程序速度显著降低

以下是while循环(
shape=(10001000,3)
)的示例:

i=0
j=0
而我
-->

def(x):
如果x 0,则返回1,否则返回0
f=np.矢量化(f)
arr=f(arr)
编辑:另一个while循环

i = 0
j = 0
while i < arr1.shape[0]:
    while j < arr1.shape[1]:

        if arr1[i, j, 0] == 0 and arr1[i, j, 1] == 0 and arr1[i, j, 2] == 0:
            arr1[i, j, :] = arr1[i, j, :]
        else:
            arr1[i, j, :] = arr2[i, j, :]

        j = j + 1
    j = 0
    i = i + 1
# Prepare data
m = 100
n = 100
d = 3
np.random.seed(0)
arr = np.random.randint(0, 11, size=(m, n, d))

true_mask = np.random.randint(0, 2, size=(m, n, 1), dtype=np.bool)
true_mask = np.dstack([true_mask] * d)

arr[true_mask] = 0

arr1 = arr.copy()
arr2 = -1 * np.ones_like(arr1)

In [84]: v1 = vectorized(arr1, arr2)

In [85]: v2 = original(arr1, arr2)

In [86]: np.allclose(v1, v2)
Out[86]: True

In [87]: %timeit v1 = vectorized(arr1, arr2)
1000 loops, best of 3: 284 µs per loop

In [88]: %timeit v2 = original(arr1, arr2)
100 loops, best of 3: 12.6 ms per loop
i=0
j=0
而我
有没有办法加快速度?我不知道怎么做。

编辑 在匆忙中,我先前的回答是错误的。感谢@gboffi指出这一点

第一部分 第二部分
让我们生成一些测试数据

In [61]: np.random.seed(0) ; a = np.random.randint(10, size=(3,4,2))-3

In [62]: a
Out[62]: 
array([[[ 2, -3],
        [ 0,  0],
        [ 4,  6],
        [ 0,  2]],

       [[-1,  1],
        [ 4,  3],
        [ 5,  5],
        [-2,  3]],

       [[ 4,  4],
        [ 5, -2],
        [ 2,  6],
        [ 5,  6]]])
根据问题中的示例,第一个元素位于[1…5]中的每一行都变成一行1,其他所有行都变成一行0

让我们生成一个反映OP正在执行的测试的掩码(只涉及上面显示的每行的第一个元素)

让我们显示结果

In [66]: a
Out[66]: 
array([[[1, 1],
        [0, 0],
        [1, 1],
        [0, 0]],

       [[0, 0],
        [1, 1],
        [1, 1],
        [0, 0]],

       [[1, 1],
        [1, 1],
        [1, 1],
        [1, 1]]])
如果我正确解释OP示例,这就是他们想要的


我不得不说,答案显然与我的相似

In [67]: np.random.seed(0) ; a = np.random.randint(10, size=(3,4,2))-3
In [68]: t = (0 < a) & (a <= 5)
In [69]: a[t] = 1
In [70]: a[~t]= 0
In [71]: a
Out[71]: 
array([[[1, 0],
        [0, 0],
        [1, 0],
        [0, 1]],

       [[0, 1],
        [1, 1],
        [1, 1],
        [0, 1]],

       [[1, 1],
        [1, 0],
        [1, 0],
        [1, 0]]])
[67]中的
np.random.seed(0);a=np.random.randint(10,size=(3,4,2))-3

在[68 ]:t=(0<a)和(a)因为你标记了NUPY,你可以寻找你的答案或HINTSs。这不回答你的问题。但是如果你被困在循环中(即使你没有)考虑使用<代码> NUBA进行JIT编译。你可能会得到大的加速。<代码> ARR[I,J,:] = int(0<ARR[I,J,0 ] <代码>范围内的I(Ar.St[0)]:
是在一系列索引上循环的首选方式。速度没有差别,只是代码更干净。@jp_data_analysis,@max9111,我认为在现阶段我们不应该建议
numba
。OP需要先学会使用基本数组屏蔽和索引。而
循环的使用表明他是Python novice、 你能帮我解决第二个问题吗?:)也许以后吧。我现在要去某个地方。如果2小时后没有人解决,我会回答。再见。@freddykrueger我已经用基准更新了我的答案,并修复了原始答案中的一个错误。
def vectorized(arr1, arr2):
    mask = np.all(arr1 == 0, axis=2)
    mask = np.dstack([mask] * arr1.shape[2])
    return np.where(mask, arr1, arr2)

def original(arr1, arr2):
    i = 0
    j = 0
    while i < arr1.shape[0]:
        while j < arr1.shape[1]:

            if arr1[i, j, 0] == 0 and arr1[i, j, 1] == 0 and arr1[i, j, 2] == 0:
                arr1[i, j, :] = arr1[i, j, :]
            else:
                arr1[i, j, :] = arr2[i, j, :]

            j = j + 1

        j = 0
        i = i + 1

    return arr1
# Prepare data
m = 100
n = 100
d = 3
np.random.seed(0)
arr = np.random.randint(0, 11, size=(m, n, d))

true_mask = np.random.randint(0, 2, size=(m, n, 1), dtype=np.bool)
true_mask = np.dstack([true_mask] * d)

arr[true_mask] = 0

arr1 = arr.copy()
arr2 = -1 * np.ones_like(arr1)

In [84]: v1 = vectorized(arr1, arr2)

In [85]: v2 = original(arr1, arr2)

In [86]: np.allclose(v1, v2)
Out[86]: True

In [87]: %timeit v1 = vectorized(arr1, arr2)
1000 loops, best of 3: 284 µs per loop

In [88]: %timeit v2 = original(arr1, arr2)
100 loops, best of 3: 12.6 ms per loop
In [61]: np.random.seed(0) ; a = np.random.randint(10, size=(3,4,2))-3

In [62]: a
Out[62]: 
array([[[ 2, -3],
        [ 0,  0],
        [ 4,  6],
        [ 0,  2]],

       [[-1,  1],
        [ 4,  3],
        [ 5,  5],
        [-2,  3]],

       [[ 4,  4],
        [ 5, -2],
        [ 2,  6],
        [ 5,  6]]])
In [63]: t = np.logical_and(0<a[:,:,0],a[:,:,0]<=5)
In [64]: a[ t,:] = 1
In [65]: a[~t,:] = 0
In [66]: a
Out[66]: 
array([[[1, 1],
        [0, 0],
        [1, 1],
        [0, 0]],

       [[0, 0],
        [1, 1],
        [1, 1],
        [0, 0]],

       [[1, 1],
        [1, 1],
        [1, 1],
        [1, 1]]])
In [67]: np.random.seed(0) ; a = np.random.randint(10, size=(3,4,2))-3
In [68]: t = (0 < a) & (a <= 5)
In [69]: a[t] = 1
In [70]: a[~t]= 0
In [71]: a
Out[71]: 
array([[[1, 0],
        [0, 0],
        [1, 0],
        [0, 1]],

       [[0, 1],
        [1, 1],
        [1, 1],
        [0, 1]],

       [[1, 1],
        [1, 0],
        [1, 0],
        [1, 0]]])