78

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)のような名前の関数がないことに驚いています。

4

6 に答える 6

66

提案する内容は非常に高速ですが、より明確な形式で読みやすさを向上させることができます。

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] た場合を処理する)を介して行われる可能性があるためだと思います。:

ただし、より明確な2番目のソリューション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
于 2009-10-20T08:13:50.370 に答える
31

私は以下を使用します:

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)

于 2011-05-07T19:05:11.647 に答える
8

したがって、あなたが示したように、最初の次元を簡単に繰り返すことができます。任意の次元に対してこれを行う別の方法は、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)

編集:これに対処するためにnumpyにPRを送信したことをコメントします: https ://github.com/numpy/numpy/pull/3262 。コンセンサスは、これではnumpyコードベースに追加するには不十分であるというものでした。これを行うには、np.rollaxisを使用するのが最善の方法だと思います。インターレーターが必要な場合は、iter()でラップします。

于 2013-04-18T14:07:13.187 に答える
5

機能がないと思います。関数を書いたとき、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,)]
于 2009-10-20T14:10:18.487 に答える
3

numpy.shapeを使用してディメンションを取得し、範囲を指定してそれらを反復処理できます。

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

for r in range(n0):
    print(c[r,:,:])
于 2019-08-08T16:39:13.383 に答える
1

以下はまさにあなたが探しているものです:

for x in np.moveaxis(X, axis, 0):
于 2021-06-14T20:41:54.593 に答える