如何列舉多維度陣列索引? - tsungjung411/python-study GitHub Wiki

  • 如何列舉多維度陣列索引?
  • How to iterate multi-dimensional array indices?
  • How to list n-dim(ndim) array indices(index)?

函數實作:

import numpy

'''
moves to the next index from 'current_index'

input:
    array: n-dim array
    current_index: a tuple consists of each dimension's index, e.g. (1,2,3)

output:
    a tuple (the next index), e.g. (1,2,4(=3+1))
'''
def get_next_index(array,  current_index):
    shape = array.shape
    
    # copies 'current_index', and moves to the next index
    next_index = list(current_index)
    next_index[array.shape[-1]] += 1
    
    carry = 0
    for idx in reversed(range(len(shape))):
        next_index[idx] = next_index[idx] + carry
        if next_index[idx] < shape[idx]:
            break;
        else:
            carry = int(next_index[idx] / shape[idx])
            next_index[idx] = next_index[idx] % shape[idx]
        # end-of-if
    # end-of-for
    
    return tuple(next_index)
# end-of-def

測試1

a = numpy.array([
    ['000','001'],['010','011'],['020','021'](/tsungjung411/python-study/wiki/'000','001'],['010','011'],['020','021'),
    ['100','101'],['110','111'],['120','121'](/tsungjung411/python-study/wiki/'100','101'],['110','111'],['120','121'),
    ['200','201'],['210','211'],['220','221'](/tsungjung411/python-study/wiki/'200','201'],['210','211'],['220','221'),
    ['300','301'],['310','311'],['320','321'](/tsungjung411/python-study/wiki/'300','301'],['310','311'],['320','321')
])
print('陣列大小:', a.shape)
print('------------------')
index0 = tuple(numpy.zeros(len(a.shape), dtype=numpy.int32)) # =(0,0,0), start index
index = index0
while True:
    print(index)
    index = get_next_index(a, index)
    if index == index0:
        break;
    # end-of-if
# end-of-while

執行結果1:

陣列大小: (4, 3, 2)
------------------
(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(0, 1, 1)
(0, 2, 0)
(0, 2, 1)
(1, 0, 0)
(1, 0, 1)
(1, 1, 0)
(1, 1, 1)
(1, 2, 0)
(1, 2, 1)
(2, 0, 0)
(2, 0, 1)
(2, 1, 0)
(2, 1, 1)
(2, 2, 0)
(2, 2, 1)
(3, 0, 0)
(3, 0, 1)
(3, 1, 0)
(3, 1, 1)
(3, 2, 0)
(3, 2, 1)

測試2:不同起始索引

a = numpy.array([
    ['000','001'],['010','011'],['020','021'](/tsungjung411/python-study/wiki/'000','001'],['010','011'],['020','021'),
    ['100','101'],['110','111'],['120','121'](/tsungjung411/python-study/wiki/'100','101'],['110','111'],['120','121'),
    ['200','201'],['210','211'],['220','221'](/tsungjung411/python-study/wiki/'200','201'],['210','211'],['220','221'),
    ['300','301'],['310','311'],['320','321'](/tsungjung411/python-study/wiki/'300','301'],['310','311'],['320','321')
])
print('陣列大小:', a.shape)
print('------------------')
index = (0,0,8) # start index
while True:
    print(index)
    index = get_next_index(a, index)
    if index == (0,0,0):
        break;
    # end-of-if
# end-of-while

執行結果2:

陣列大小: (4, 3, 2)
------------------
(0, 0, 8)
(1, 1, 1)
(1, 2, 0)
(1, 2, 1)
(2, 0, 0)
(2, 0, 1)
(2, 1, 0)
(2, 1, 1)
(2, 2, 0)
(2, 2, 1)
(3, 0, 0)
(3, 0, 1)
(3, 1, 0)
(3, 1, 1)
(3, 2, 0)
(3, 2, 1)