- 取得連結
- 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,
,np.newaxis 則
- 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] 的
則回傳 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 (前幾個
需一致),等同 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 決定,
- 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(广播)机制
留言
張貼留言