python nditer---反復配列

5016 ワード

反復オブジェクトnditerは、1つまたは複数の配列に柔軟にアクセスする方法を提供する.
単一配列の反復(Single Array Iteration)
反復器の最も基本的なタスクは、配列要素へのアクセスを完了することができ、反復器インタフェースは、各要素を次々と提供することができる.
例:
a = np.arange(6).reshape(2, 3)
for x in np.nditer(a):
    print x, " "
0  1  2  3  4  5  
この反復方式では、選択された順序は、標準CまたはFortran順序を使用するのではなく、配列メモリレイアウトと一致することに注意しなければならない.これは、効率を使用するために設計されています.これは、デフォルトでは各要素にアクセスするだけで、特定の順序を考慮する必要がないことを反映しています.上記の配列の回転を反復することでこの点を見ることができ,C順序でアクセスできる.
配列の回転のcopyの方式は比較して、あります:
a = np.arange(6).reshape(2, 3)
for x in np.nditer(a.T):
    print x,
print "
" for x in np.nditer(a.T.copy(order = 'C')): print x, 0 1 2 3 4 5 0 3 1 4 2 5

上記の例から、aとa.Tの遍歴順序は同じであり、メモリ内の記憶順序も同じであるが、a.T.copy(order='C')の遍歴結果は、前の2つの記憶方式とは異なるため、異なることがわかる.デフォルトは行ごとのアクセスです.
制御反復順序(Controlling Iteration Order)
メモリ内の要素の分布にかかわらず、配列に特定の順序でアクセスすることが重要になる場合があります.従ってnditerは、この要件を達成するためにシーケンスパラメータ(order parameter)の方法を提供する.デフォルトではorder='K'ですが、上記のアクセス方法です.また、order='C'とorder='F'があります.Cは行ごとのアクセスであり、Fは列ごとのアクセスである.
a = np.arange(6).reshape(2, 3)
for x in np.nditer(a, order = 'F'):
    print x,
print "
" for x in np.nditer(a.T, order = 'C'): print x, 0 3 1 4 2 5 0 3 1 4 2 5

配列値の変更(Modify Array Value)
デフォルトでは、nditerは入力配列を
読み取り専用オブジェクト.配列要素を変更するには、読み書き(
read-write)または書き込みのみ(
write-only)モード.これはそれぞれ
オペランドフラグ制御.一般に、Pythonの付与値は、既存の変数を変更するのではなく、ローカルまたはグローバル変数辞書の参照を変更するだけです.
a = np.arange(6).reshape(2, 3)
print a

for x in np.nditer(a, op_flags = ['readwrite']):
    x[...] = 2*x

print a

[[0 1 2]
 [3 4 5]]
[[ 0  2  4]
 [ 6  8 10]]

外部ループの使用
  In all the examples so far, the elements of a are provided by the iterator one at a time, because all the looping logic is internal to the iterator. While this is simple and convenient, it is not very efficient. A better approach is to move the one-dimensional innermost loop into your code, external to the iterator. This way, NumPy’s vectorized operations can be used on larger chunks of the elements being visited.   The nditer will try to provide chunks that are as large as possible to the inner loop. By forcing ‘C’ and ‘F’ order, we get different external loop sizes. This mode is enabled by specifying an iterator flag.   Observe that with the default of keeping native memory order, the iterator is able to provide a single one-dimensional chunk, whereas when forcing Fortran order, it has to provide three chunks of two elements each.
a = np.arange(6).reshape(2, 3)

for x in np.nditer(a, flags = ['external_loop']):
    print x

for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
    print x

[0 1 2 3 4 5]

[0 3]
[1 4]
[2 5]

単一インデックスまたは複数インデックスのトレース
  During iteration, you may want to use the index of the current element in a computation. For example, you may want to visit the elements of an array in memory order, but use a C-order, Fortran-order, or multidimensional index to look up values in a different array.   The Python iterator protocol doesn’t have a natural way to query these additional values from the iterator, so we introduce an alternate syntax for iterating with an nditer. This syntax explicitly works with the iterator object itself, so its properties are readily accessible during iteration. With this looping construct, the current value is accessible by indexing into the iterator, and the index being tracked is the property index or multi_index depending on what was requested.   The Python interactive interpreter unfortunately prints out the values of expressions inside the while loop during each iteration of the loop. We have modified the output in the examples using this looping construct in order to be more readable.
a = np.arange(6).reshape(2, 3)
it = np.nditer(a, flags = ['f_index'])
while not it.finished:
    print '%d' % (it[0], it.index),
    it.iternext()

print '
' it = np.nditer(a, flags = ['multi_index']) while not it.finished: print '%d' % (it[0], it.multi_index), it.iternext() print '
' it = np.nditer(a, flags = ['multi_index'], op_flags = ['writeonly']) while not it.finished: it[0] = it.multi_index[1] - it.multi_index[0] it.iternext() print a 0<0> 1<2> 2<4> 3<1> 4<3> 5<5> 0 1 2 3 4 5 [[ 0 1 2] [-1 0 1]]

単一のインデックスは列順に要素の下付きを出力し、マルチインデックスは要素の座標、例えば要素3の座標(1,0)を出力し、はっきりしないので、3 D配列のマルチインデックス結果を見てみましょう.
b = np.arange(27).reshape(3, 3, 3)
it = np.nditer(b, flags = ['multi_index'])
while not it.finished:
    print '%d' % (it[0], it.multi_index),
    it.iternext()

0 1 2 3 4 5 
6 7 8 9 10 11
12 13 14 15 16 
17 18 19 20 21 
22 23 24 25 26   

出典:https://docs.scipy.org/doc/numpy-1.10.0/reference/arrays.nditer.html