2013-04-20 4 views
2

Существует много способов перебора 2D-массива. Примеры ниже.Есть ли более читаемый (и эффективный) способ итерации по ndarray?

Большинство из этих подходов, в то время как функциональные, кажутся мне трудными для чтения. Некоторые из них очень дороги, и большинство из них не хорошо обобщаются для N-измерений.

Есть ли более читаемый способ, предпочтительно эффективный с точки зрения вычисления и обобщающий для ND, для итерации по всем наборам координат в ndarray?

arr = np.arange(100).reshape([10,10]) 
x,y = np.indices(arr.shape) 

for i,j in zip(x.flat,y.flat): 
    dosomething(arr[i,j]) 

for i,j in np.nditer(np.indices(arr.shape).tolist()): 
    dosomething(arr[i,j]) 

for i in xrange(arr.shape[0]): 
    for j in xrange(arr.shape[1]): 
     dosomething(arr[i,j]) 

for i,j in itertools.product(range(arr.shape[0], range.shape[1])): 
    dosomething(arr[i,j]) 

# on further thought, maybe this one is OK? 
for ind in xrange(arr.size): 
    i,j = np.unravel_index(ind, arr.shape) 
    dosomething(arr[i,j]) 

for i,j in itertools.product(*map(xrange, arr.shape)): 
    dosomething(arr[i,j]) 

(последний из Pythonic way of iterating over 3D array)

Вопрос, который я действительно хотел ответ был «как я могу получить x, y индексы массива?» Ответ:

for i,j in (np.unravel_index(ind,arr.shape) for ind in xrange(arr.size)): 
    dosomething(arr[i,j]) 

(np.unravel_index(ind,arr.shape) for ind in xrange(arr.size)) довольно читаемый и эффективный генератор.

Но на вопрос, заданный в заголовке, другие (связанные) ответы лучше (np.nditer, np.enumerate)

+0

После публикации я заметил это ... http://stackoverflow.com/questions/6967463/iterating-over-a-numpy-array, что может быть ответом. – keflavich

+0

Я просто писал «ndenumerate» в качестве решения; это то, что я делаю, в тех редких случаях мне это нужно. – DSM

+0

Вперед и поставим его ... учитывая, что я задал этот вопрос около 10 минут, не найдя ответа, я думаю, что поисковые термины для этого стиля вопроса еще не насыщены. – keflavich

ответ

1

Из ваших примеров, кажется, что вы хотите перебрать свои массивы в C-прилежащей стиле. Если вы заботитесь только об элементах, а не индексы, могут быть использованы следующие:

for e in arr.flat: 
    dosomething(e) 

Конечно, это быстрее, чем все альтернативы. Однако, если вы хотите, чтобы некоторые напуганные вещи с индексами, этот метод не может быть использован (используйте ndenumerate - ваш связанный SO-ответ - для этого). Это можно использовать с N-dims.

Смежные вопросы