代码之家  ›  专栏  ›  技术社区  ›  user52366

在ndarray的某些(但不是所有)维度上迭代

  •  1
  • user52366  · 技术社区  · 6 年前

    我在python中有一个三维ndarray,并希望以元素方式沿着三个边距中的两个进行迭代。

    更确切地说,例如,我希望遍历所有(x,y)对,但将z数据作为数组保存在一起。

    [ f(z) for z in all_xy_pairs(the_ndarray) if g(z) == True ]
    

    我想用“重塑”这个词如下

    import numpy as np
    # silly example
    ii=np.arange(0,3*9,1).reshape(3,3,3)
    [ z for z in ii.reshape(9,-1) if z[1]>10 ]
    

    但是我更喜欢一个迭代器,我可以通过它来传递要迭代的数组边距(在上面的例子中,边距=[0,1]。在伪代码中,上面的示例将变成

    [ z for z in iterate_over_margins(ii, margins=[0,1]) if z[1]>10 ]
    

    nditer 但这不符合我的要求。

    2 回复  |  直到 6 年前
        1
  •  1
  •   user545424    6 年前

    您可以通过沿着这些列索引来选择麻木数组的某些行/列,即 z[i,j,k] . 为了选择 全部的 可以使用的特定维度中的元素 :

    for i in range(z.shape[0]):
        for j in range(z.shape[2]):
            print(z[i,:,j])
    
        2
  •  0
  •   javidcf    6 年前

    这回答了一个稍微不同的问题,但是,正如您肯定知道的,NumPy通常从使用矢量化操作中受益匪浅,因此如果 f g 可以矢量化,也可以考虑对包含序列中所有迭代元素的数组进行操作。你可以通过一些重塑:

    import numpy as np
    
    # "Unrolls" an array along the given axes
    def unroll_axis(a, axis):
        a = np.asarray(a)
        # This so it works with a single dimension or a sequence of them
        axis = np.atleast_1d(axis)
        # Put unrolled axes at the beginning
        a = np.moveaxis(a, axis, range(len(axis)))
        # Unroll
        return a.reshape((-1,) + a.shape[len(axis):])
    
    # Example
    a = np.arange(27).reshape((3, 3, 3))
    print(unroll_axis(a, (0, 2)))
    # [[ 0  3  6]
    #  [ 1  4  7]
    #  [ 2  5  8]
    #  [ 9 12 15]
    #  [10 13 16]
    #  [11 14 17]
    #  [18 21 24]
    #  [19 22 25]
    #  [20 23 26]]
    

    是矢量化的,你可以

    the_array_unrolled = unroll_axis(the_array, (0, 2))
    result = f(the_array_unrolled[g(the_array_unrolled)])