https://numpy.org/doc/stable/user/basics.indexing.html
https://numpy.org/doc/stable/reference/arrays.indexing.html
Array indexing refers to any use of the square brackets ([]) to index array values.
Attention: Whereas slicings on lists and tuples create new objects, a slicing operation on an array creates a view on the original array.
If the number of objects in the selection tuple is less than the dimension N, then : is assumed for any subsequent dimensions.
a = np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # Indexing: a[0] first, a[1] second, a[-1] last # General syntax for slicing: a[start:stop], a[start:stop:step] # Note that stop is not included. a[2:5], a[:3], a[4:], a[::2] (even), a[1::2] (odd), a[::3] # Exercise: negative start/stop/step, a[::-1] (reversed)
b = np.arange(12).reshape((3,4)) # array([[ 0, 1, 2, 3], # [ 4, 5, 6, 7], # [ 8, 9, 10, 11]]) # Indexing: b[1][2] or b[1,2] gives 6. # b[1][2] is less efficient, because a new temporary array is created! b[1] # the same as b[1,:] # array([4, 5, 6, 7]), it is a view # Slicing b[:2,2:] # array([[2, 3], # [6, 7]]) top right b[1:,:] # array([[ 4, 5, 6, 7], # [ 8, 9, 10, 11]]) bottom part b[:,3:] # array([[ 3], # [ 7], # [11]]) right part b[::2,::3] # array([[ 0, 3], # [ 8, 11]]) b[:,1] # array([1, 5, 9]), shape=(3,) b[1,:] # array([4, 5, 6, 7]), shape=(4,) # Exercise: only even/odd indexes, a sparse sample (every k)
c = np.arange(24).reshape((2,3,4)) # Indexing: c[1,2,3] or c[1][2,3] or c[1,2][3] or c[1][2][3] gives 23. # c[1,2,3] is the most efficient. # Slicing c[:1,1:] # equivalent to c[:1,1:,:] c[:1] # equivalent to c[:1,:,:]
a = np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) b = a[2:6] # array([2, 3, 4, 5]) this is a view! b[0] = 22 b[1] = 23 print(a) # array([ 0, 1, 22, 23, 4, 5, 6, 7, 8, 9]) np.may_share_memory(a, b) # True c = a.reshape((2, 5)) np.may_share_memory(a, c) # True # Check if array owns it's data. print(a.base) # None, 'a' owns data print(b.base) # [ 0 1 22 23 4 5 6 7 8 9], 'a' is the base of 'b'
NumPy arrays may be indexed with other arrays (index arrays). For all cases of index arrays, what is returned is a copy of the original data, not a view as one gets for slices.
a = np.array( [20, 30, 40, 50] ) a > 35 # array([False, False, True, True]) a[a > 35] # array([40, 50]), selecting items # Boolean arrays are "mask" index arrays. a[ np.array([1, 1, 3, 3, -2]) ] # array([30, 30, 50, 50, 40]) # Index array is of integer type here. Negative values are permitted. a[ np.array([[1, 1], [2, 3]]) ] # array([[30, 30], # [40, 50]])
b = np.arange(10).reshape(2, 5) # array([[0, 1, 2, 3, 4], # [5, 6, 7, 8, 9]]) b % 2 == 0 # array([[ True, False, True, False, True], # [False, True, False, True, False]]) b[b % 2 == 0] # array([0, 2, 4, 6, 8]) even numbers, shape (5,) b[b % 2 == 0] += 100 # selected items are changed in b! # array([[100, 1, 102, 3, 104], # [ 5, 106, 7, 108, 9]])
c = np.arange(35).reshape(5,7) # array([[ 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, 27], # [28, 29, 30, 31, 32, 33, 34]]) c[ np.array([0,2,4]), np.array([0,1,2]) ] # array([ 0, 15, 30]) # Selected items are c[0,0], c[2,1], c[4,2]. c[ np.array([0,2,4]), 1 ] # broadcasting # array([ 1, 15, 29]) # The same as c[ np.array([0,2,4]), np.array([1,1,1]) ] # Selected items are c[0,1], c[2,1], c[4,1]. c[ np.array([0,2,4]) ] # The same as c[ np.array([0,2,4]), : ]. # Index arrays may be combined with slices. # array([[ 0, 1, 2, 3, 4, 5, 6], # [14, 15, 16, 17, 18, 19, 20], # [28, 29, 30, 31, 32, 33, 34]]) c[ c > 20 ] # the result is a 1-D array # array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]) # Structural indexing tools. c.shape # (5, 7) c[:,np.newaxis,:].shape # (5, 1, 7) # There are no new elements in the array, # just that the dimensionality is increased.