- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
程式語言:Python
Package:numpy
官方文件
簡介:NumPy indexing 的使用
obj 的型態會影響賦於的 array 是 view 還是 copy
numpy 中的 broadcasting(广播)机制
Package:numpy
官方文件
簡介:NumPy indexing 的使用
Indexing
ndarrays indexing 的方法,即是 x[obj]obj 的型態會影響賦於的 array 是 view 還是 copy
- view:與其他 array 共用空間,改值會互相影響
- copy:與其他 array 不共用空間,改值不會互相影響
import numpy as np x = np.array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]]) view = x[1:2, 1:3] copy = x[1:2, [1, 2]] print(view) # [[4 5]] view[0] = 100 print(view) # [[100 100]] print(x) # [[ 0 1 2] # [ 3 100 100] # [ 6 7 8] # [ 9 10 11]] print(copy) # [[4 5]] copy[0] = 200 print(copy) # [[200 200]] print(x) # [[ 0 1 2] # [ 3 100 100] # [ 6 7 8] # [ 9 10 11]]
Basic Slicing and Indexing
- view 型態
- obj
- slice object (start:stop:step)
import numpy as np x = np.array([1, 2, 3, 4]) view = x[-1::-1] print(view) # [4 3 2 1] view[0] = 100 print(x) # [ 1 2 3 100]
- an integer
import numpy as np x = np.array([[1, 2], [3, 4]]) view = x[:, 1] print(view) # [2 4] view[0] = 100 print(x) # [[ 1 100] # [ 3 4]]
- a tuple of slice objects and integers
import numpy as np x = np.array([[1, 2], [3, 4]]) view = x[(slice(0,2), 1)] # 等同 x[0:2, 1] print(view) # [2 4] view[0] = 100 print(x) # [[ 1 100] # [ 3 4]]
- ... (Ellipsis),表示剩餘的其他維度,等同 (:, :, :, ...),甚至可能為空
import numpy as np x = np.array([[1, 2], [3, 4]]) view = x[..., 1] print(view) # [2 4] view[0] = 100 print(x) # [[ 1 100] # [ 3 4]]
- np.newaxis
import numpy as np x = np.array([[1, 2], [3, 4]]) # 等同 view = x[:, None] view = x[:, np.newaxis] print(view.shape) # (2, 1, 2) print(view) # [[[1 2]] # [[3 4]]] view[0] = 100 print(x) # [[100 100] # [ 3 4]]
- dimension
- 若為 integer, \(D = D - 1\),np.newaxis 則 \(D = D + 1\)
import numpy as np x = np.ones((1, 2, 3, 4, 5, 6)) print(x.shape) # (1, 2, 3, 4, 5, 6) print(x[:].shape) # (1, 2, 3, 4, 5, 6) print(x[:, 1].shape) # (1, 3, 4, 5, 6) print(x[:, 0:1].shape) # (1, 1, 3, 4, 5, 6) print(x[0:1, ...].shape) # (1, 2, 3, 4, 5, 6) print(x[:, :, np.newaxis].shape) # (1, 2, 1, 3, 4, 5, 6)
- 若 x[obj] 的 \(D = 1\) 則回傳 scalar,此時不影響原 array
import numpy as np x = np.array([1, 2, 3, 4]) view = x[0] print(type(view)) # <class 'numpy.int32'> view = 100 print(x) # [1 2 3 4]
- 等效表示
- In python
x[(exp1, exp2, ..., expN)] == x[exp1, exp2, ..., expN]
- 只有 interger 可拆分
import numpy as np x = np.arange(120).reshape((2, 3, 4, 5)) print(x[0, ..., 1:2, 0, 0]) # [20] print(x[0][..., 1:2, 0, 0]) # [20] print(x[0][...][1:2][0, 0]) # [20 21 22 23 24] print(x[0][...][1:2][0][0]) # [20 21 22 23 24] print(x) # [[[[ 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] # [ 35 36 37 38 39]] # # [[ 40 41 42 43 44] # [ 45 46 47 48 49] # [ 50 51 52 53 54] # [ 55 56 57 58 59]]] # # # [[[ 60 61 62 63 64] # [ 65 66 67 68 69] # [ 70 71 72 73 74] # [ 75 76 77 78 79]] # # [[ 80 81 82 83 84] # [ 85 86 87 88 89] # [ 90 91 92 93 94] # [ 95 96 97 98 99]] # # [[100 101 102 103 104] # [105 106 107 108 109] # [110 111 112 113 114] # [115 116 117 118 119]]]]
Advanced Indexing
- copy 型態
- obj
- integers (broadcasting 經常使用,後述會再說明)
import numpy as np x = np.arange(9).reshape(3, 3) copy = x[[1, 2], [0, 1]] print(copy) # [3 7] copy[0] = 100 print(x) # [[0 1 2] # [3 4 5] # [6 7 8]]
- boolean ndarrays (前幾個 \(D\) 需一致),等同 x[obj.nonzero()]
import numpy as np x = np.arange(9).reshape(3, 3) copy = x[np.array([[True, False, True], [False, True, False], [False, False, False]])] print(copy) # [0 2 4] copy[0] = 100 print(x) # [[0 1 2] # [3 4 5] # [6 7 8]]
- dimension
- integers 依組合不同,會得到不同的結果
import numpy as np x = np.arange(90).reshape((10, 9)) print(x.shape) # (10, 9) # 等同 x.take([[1, 2]], axis=1) result = x[:, [[1, 2]], ...] print(result.shape) # (10, 1, 2) # 等同 x.take([[1, 2]], axis=0) result = x[..., [[1, 2]], :] print(result.shape) # (1, 2, 9) result = x[[1, 2], ..., [0]] print(result.shape) # (2, ) result = x[[1, 2]] print(result.shape) # (2, 9)
import numpy as np x = np.arange(10*9*8*7).reshape((10, 9, 8, 7)) print(x.shape) # (10, 9, 8, 7) # 等同 x.take([[1, 2]], axis=1) result = x[:, [[1, 2]], ...] print(result.shape) # (10, 1, 2, 8, 7) # 等同 x.take([[1, 2]], axis=2) result = x[..., [[1, 2]], :] print(result.shape) # (10, 9, 1, 2, 7) result = x[:, [1, 2], [0], :] print(result.shape) # (10, 2, 7) result = x[:, [1, 2], :, [0]] print(result.shape) # (2, 10, 8) result = x[[1, 2], [0]] print(result.shape) # (2, 8, 7)
- boolean array 依 obj 的 dimension 決定,\(D = D_x - D_{obj} +1\)
import numpy as np x = np.arange(60).reshape(3, 4, 5) print(x.shape) # (3, 4, 5) print(x[x>15].shape) # (44,) print(x[[True, True, False]].shape) # (2, 4, 5) ind = np.array([[True, True, False, True], [True, True, False, True], [True, True, False, False]]) print(x[ind].shape) # (8, 5)
Broadcasting
- 規則
- dimension 相同
- dimension=1 自動延展
- 平常範例
import numpy as np x = np.arange(6).reshape(2,3) y = np.arange(3).reshape(3,1) z = x*y # operands could not be broadcast together with shapes (2,3) (3,1)
import numpy as np x = np.arange(3).reshape(3,1) y = np.arange(3).reshape(3,1) z = x*y print(x.shape) # (3, 1) print(y.shape) # (3, 1) print(z.shape) # (3, 3)
import numpy as np x = np.arange(3).reshape(1,3) y = np.arange(3).reshape(3,1) z = x*y print(x.shape) # (1, 3) print(y.shape) # (3, 1) print(z.shape) # (3, 3)
import numpy as np x = np.arange(3) y = np.arange(3).reshape(3,1) z = x*y print(x.shape) # (3, ) print(y.shape) # (3, 1) print(z.shape) # (3, 3)
- index 範例
import numpy as np x = np.array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]]) rows = np.array([0, 3], dtype=np.intp) columns = np.array([0, 2], dtype=np.intp) rowsT = rows[:, np.newaxis] print("rows.shape {}, columns.shape {}".format(rowsT.shape, columns.shape)) # rows.shape (2, 1), columns.shape (2,) print(x.shape) # (4, 3) # 以下兩者等價 print(x[rowsT, columns].shape) # (2, 2) print(x[np.ix_(rows, columns)].shape) # (2, 2)
Field Access
- view 型態
- obj
- strings
import numpy as np x = np.zeros((2,2), dtype=[('a', np.int32), ('b', np.float64, (3,3))]) print(x) # [[(0, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) # (0, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]])] # [(0, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) # (0, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]])]] print(x['a'].shape) # (2, 2) print(x['a'].dtype) # dtype('int32') print(x['b'].shape) # (2, 2, 3, 3) print(x['b'].dtype) # dtype('float64') view = x['a'] print(view) # [[0 0] # [0 0]] view[0] = 100 print(x) # [[(100, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) # (100, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]])] # [( 0, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) # ( 0, [[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]])]]
Flat Iterator indexing
- view 型態
- 範例
import numpy as np x = np.zeros((2,2)) print(x) # [[ 0. 0.] # [ 0. 0.]] view = x.flat print(view[:]) # [ 0. 0. 0. 0.] view[0] = 100 print(x) # [[ 100. 0.] # [ 0. 0.]]
Note
- 可用內建的 slice
# 等同 x[1:10:5,::-1] obj = (slice(1,10,5), slice(None,None,-1)) x[obj]
- 不同情況,會得到不同的結果 view, copy , scalar
import numpy as np x = np.arange(9).reshape(3,3) print(x) # [[0 1 2] # [3 4 5] # [6 7 8]] copy = x[(1,2),] print(copy) # [[3 4 5] # [6 7 8]] copy[0] = 100 print(x) # [[0 1 2] # [3 4 5] # [6 7 8]] # 等同 view = x[1,2] scalar = x[(1,2)] print(scalar) # 5 scalar = 200 print(x) # [[0 1 2] # [3 4 5] # [6 7 8]] copy = x[[1,2]] print(copy) # [[3 4 5] # [6 7 8]] copy[0] = 300 print(x) # [[0 1 2] # [3 4 5] # [6 7 8]] view = x[[1,slice(None)]] print(view) # [3 4 5] view[0] = 400 print(x) # [[ 0 1 2] # [400 4 5] # [ 6 7 8]]
- NumPy indexing 建議 type 為 intp
import numpy as np ind = np.array([[0, 0], [3, 3]], dtype=np.intp)
- advanced indexing 若 index 超出範圍,並不會出現 IndexError
import numpy as np x = np.zeros((8, 8)) print(x[[], [100]]) # 不會出現錯誤
參考
Numpy 笔记(二): 多维数组的切片(slicing)和索引(indexing)numpy 中的 broadcasting(广播)机制
留言
張貼留言