首页 > 解决方案 > 使用 nditer() 从 numpy 1.15.3 遍历所有元素的 3D numpy 数组迭代列表

问题描述

我有一个 3D Numpy 数组列表,我想迭代这个结构的每个元素并使用 if statemets 进行一些更改。下面的代码执行我想做的事情:

for counter1, entry in enumerate(all_frames_flow):
    for counter2, entry2 in enumerate(entry):
        for counter3, entry3 in enumerate(entry2):
            for counter4, entry4 in enumerate(entry3):
                if entry4 < -20.0:
                    all_frames_flow[counter1][counter2][counter3][counter4]=-20.0
                if entry4 > 20.0:
                    all_frames_flow[counter1][counter2][counter3][counter4]=20.0
                all_frames_flow[counter1][counter2][counter3][counter4]/=20

但我想知道是否有更蟒蛇的方式。在numpy >=1.15.0我从文档中尝试了这个新代码但它失败了,它没有返回我想要的结果,我可以看到大于的值abs(20),我想知道为什么会这样:

for counteref, _ in enumerate(backup2):                    
    with np.nditer(backup2[counteref], op_flags=['readwrite'], order = 'K') as it:
            for x in it:
                #print x
                if (x < -20.0):
                    x=-20.0
                if (x > 20.0):
                    x = 20.0
                x/=20.0

标签: python-2.7numpyfor-loopiteration

解决方案


我更喜欢numpy.ndindex来为自己节省一些嵌套循环并保持函数结构合理平坦。我觉得numpy.nditer对于有更多数组循环的情况更有用:

mat = np.random.rand(2, 3, 4) * 100 - 50
for i in np.ndindex(*mat.shape):
    if mat[i] < -20:
        mat[i] = -20
    if mat[i] > 20:
        mat[i] = 20  
mat /= 20.0

另一种方法是使用numpy.where进行条件和操作,它们不依赖于特定索引但适用于整个数组:

mat = np.random.rand(2, 3, 4) * 100 - 50
#              Condition, if True, if False
mat = np.where(mat < -20,     -20,     mat)
mat = np.where(mat > +20,      20,     mat)
mat /= 20.0

对于您在定义范围之外裁剪数组值的特定情况numpy.clip(arr, a_min, a_max)可能是最简单和最快的方法。


推荐阅读