遍历numpy.array的任意维

ffvjumwh  于 2023-01-13  发布在  其他
关注(0)|答案(6)|浏览(159)

是否有函数可以在numpy数组的任意维上获得迭代器?
在第一维上迭代很容易...

In [63]: c = numpy.arange(24).reshape(2,3,4)

In [64]: for r in c :
   ....:     print r
   ....: 
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]]

但是在其他维度上迭代就比较困难了,比如最后一个维度:

In [73]: for r in c.swapaxes(2,0).swapaxes(1,2) :
   ....:     print r
   ....: 
[[ 0  4  8]
 [12 16 20]]
[[ 1  5  9]
 [13 17 21]]
[[ 2  6 10]
 [14 18 22]]
[[ 3  7 11]
 [15 19 23]]

我自己正在制作一个生成器来完成这个任务,但是我很惊讶没有一个名为numpy.ndarray.iterdim(axis=0)的函数来自动完成这个任务。

lfapxunr

lfapxunr1#

你的建议相当快,但清晰的表格可以提高易读性:

for i in range(c.shape[-1]):
    print c[:,:,i]

或者,更好(更快、更一般和更明确):

for i in range(c.shape[-1]):
    print c[...,i]

然而,上面的第一种方法似乎比swapaxes()方法慢大约两倍:

python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
    'for r in c.swapaxes(2,0).swapaxes(1,2): u = r'
100000 loops, best of 3: 3.69 usec per loop

python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
    'for i in range(c.shape[-1]): u = c[:,:,i]'
100000 loops, best of 3: 6.08 usec per loop

python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
    'for r in numpy.rollaxis(c, 2): u = r'
100000 loops, best of 3: 6.46 usec per loop

我猜想这是因为swapaxes()不复制任何数据,而且c[:,:,i]的处理可能通过通用代码(处理:被更复杂的切片替换的情况)完成。
然而,注意,更显式的第二解c[...,i]既相当易读又相当快:

python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
    'for i in range(c.shape[-1]): u = c[...,i]'
100000 loops, best of 3: 4.74 usec per loop
pgpifvop

pgpifvop2#

我会使用以下代码:

c = numpy.arange(2 * 3 * 4)
c.shape = (2, 3, 4)

for r in numpy.rollaxis(c, 2):
    print(r)

函数rolleresis创建了一个新的数组视图,在这个例子中,它将轴2移到前面,相当于操作c.transpose(2, 0, 1)

fykwrbwg

fykwrbwg3#

因此,我们可以很容易地迭代第一个维度,如前所述,对任意维度进行迭代的另一种方法是使用numpy.roltheresis()将给定维度置为第一个维度(默认行为),然后使用返回的数组(这是一个视图,因此速度很快)作为迭代器。

In [1]: array = numpy.arange(24).reshape(2,3,4)

In [2]: for array_slice in np.rollaxis(array, 1):
   ....:     print array_slice.shape
   ....:
(2, 4)
(2, 4)
(2, 4)

编辑:我会评论说,我提交了一个公关麻木解决这个问题在这里:https://github.com/numpy/numpy/pull/3262。大家一致认为这不足以增加 numpy 代码库。我认为使用np.roltheresis是最好的方法,如果你想要一个interator,把它 Package 在iter()中。

7vhp5slm

7vhp5slm4#

我猜没有函数。当我写我的函数时,我最终采用了EOL也建议的迭代。对于未来的读者,这里是:

def iterdim(a, axis=0) :
  a = numpy.asarray(a);
  leading_indices = (slice(None),)*axis
  for i in xrange(a.shape[axis]) :
    yield a[leading_indices+(i,)]
ttisahbt

ttisahbt5#

可以使用numpy.shape获取维度,然后使用range迭代这些维度。

n0, n1, n2 = numpy.shape(c)

for r in range(n0):
    print(c[r,:,:])
oewdyzsn

oewdyzsn6#

以下内容正是您正在寻找的:

for y in np.moveaxis(x, axis, 0):

相关问题