python dict
の場合、iteritems()
を使用してキーと値を同時にループできますが、NumPy配列にはこのような機能が見つかりません。次のようにidx
を手動で追跡する必要があります。
idx = 0
for j in theta:
some_function(idx,j,theta)
idx += 1
これを行うためのより良い方法はありますか?
いくつかの選択肢があります。以下は、1d NumPy配列を反復処理していることを前提としています。
range
で繰り返しますfor j in range(theta.shape[0]): # or range(len(theta))
some_function(j, theta[j], theta)
これは、 numba
で動作する3つのソリューションの 唯一 であることに注意してください。 NumPy配列を明示的に反復処理することは、通常numba
またはプリコンパイルの別の手段と組み合わせた場合にのみ効率的であるため、これは注目に値します。
enumerate
で繰り返しますfor idx, j in enumerate(theta):
some_function(idx, j, theta)
1Dアレイ用の3つのソリューションの中で最も効率的です。以下のベンチマークをご覧ください。
np.ndenumerate
で繰り返しますfor idx, j in np.ndenumerate(theta):
some_function(idx[0], j, theta)
idx[0]
の追加のインデックス作成ステップに注意してください。これは、1d NumPy配列のインデックス(shape
など)がシングルトンのタプルとして与えられるために必要です。 1次元配列の場合、np.ndenumerate
は非効率的です。その利点は、多次元配列に対してのみ示されます。
# Python 3.7, NumPy 1.14.3
np.random.seed(0)
arr = np.random.random(10**6)
def enumerater(arr):
for index, value in enumerate(arr):
index, value
pass
def ranger(arr):
for index in range(len(arr)):
index, arr[index]
pass
def ndenumerater(arr):
for index, value in np.ndenumerate(arr):
index[0], value
pass
%timeit enumerater(arr) # 131 ms
%timeit ranger(arr) # 171 ms
%timeit ndenumerater(arr) # 579 ms
たとえば、numpy.ndenumerate
を使用できます
import numpy as np
test_array = np.arange(2, 3, 0.1)
for index, value in np.ndenumerate(test_array):
print(index[0], value)
詳細については、 https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndenumerate.html を参照してください。