IT이야기

numpy.array의 임의 차원에 대해 반복

cyworld 2021. 9. 21. 20:01
반응형

numpy.array의 임의 차원에 대해 반복


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)과 같은 이름의 함수가 없다는 것에 놀랐습니다.


당신이 제안한 것은 매우 빠르지만 더 명확한 형식으로 가독성을 향상시킬 수 있습니다.

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

또는 더 나은(더 빠르고, 더 일반적이고, 더 명시적):

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

그러나 위의 첫 번째 접근 방식은 접근 방식보다 약 2배 느린 것으로 보입니다 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

나는 다음을 사용할 것입니다 :

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

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

함수 rollaxis 는 배열에 새로운 뷰를 생성합니다. 이 경우 축 2를 앞으로 이동하는 작업과 동일합니다 c.transpose(2, 0, 1).


따라서 여러분이 보여준 것처럼 첫 번째 차원을 쉽게 반복할 수 있습니다. 임의의 차원에 대해 이를 수행하는 또 다른 방법은 numpy.rollaxis()를 사용하여 주어진 차원을 첫 번째(기본 동작)로 가져온 다음 반환된 배열(보기이므로 빠름)을 반복자로 사용하는 것입니다. .

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)

EDIT: I'll comment that I submitted a PR to numpy to address this here: https://github.com/numpy/numpy/pull/3262. The concensus was that this wasn't enough to add to the numpy codebase. I think using np.rollaxis is the best way to do this, and if you want an interator, wrap it in iter().


I guess there is no function. When I wrote my function, I ended up taking the iteration EOL also suggested. For future readers, here it is:

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,)]

You can use numpy.shape to get dimensions, and then range to iterate over them.

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

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

ReferenceURL : https://stackoverflow.com/questions/1589706/iterating-over-arbitrary-dimension-of-numpy-array

반응형