NumPy 教程(第 10 章) 陣列迭代

2021-09-24 15:10:58 字數 4406 閱讀 7198

numpy 迭代器物件 numpy.nditer 提供了一種靈活訪問乙個或者多個陣列元素的方式,迭代器最基本的任務的可以完成對陣列元素的訪問

使用 arange() 函式建立乙個 2x3 陣列,並使用 nditer 對它進行迭代

in [1]: import numpy as np

in [2]: num = np.arange(6).reshape(2,3)

in [3]: num

out[3]:

array([[0, 1, 2],

[3, 4, 5]])

in [4]: for x in np.nditer(num):

...: print(x, end=', ')

...:

0, 1, 2, 3, 4, 5,

以上例項不是使用標準 c 或者 fortran 順序,選擇的順序是和陣列記憶體布局一致的,這樣做是為了提公升訪問的效率,預設是行序優先(row-major order,或者說是 c-order)

這反映了預設情況下只需訪問每個元素,而無需考慮其特定順序。我們可以通過迭代上述陣列的轉置來看到這一點,並與以 c 順序訪問陣列轉置的 copy 方式做對比

in [5]: for x in np.nditer(num.t):

...: print(x, end=', ')

...:

0, 1, 2, 3, 4, 5,

in [6]: for x in np.nditer(num.t.copy(order='c')):

...: print(x, end=', ')

...:

0, 3, 1, 4, 2, 5,

從上述例子可以看出,a 和 a.t 的遍歷順序是一樣的,也就是他們在記憶體中的儲存順序也是一樣的,但是 a.t.copy(order = 『c』) 的遍歷結果是不同的,那是因為它和前兩種的儲存方式是不一樣的,預設是按行訪問

控制遍歷順序

原始陣列

in [1]: import numpy as np

in [2]: num = np.arange(0,60,5).reshape(3,4)

in [3]: num

out[3]:

array([[ 0, 5, 10, 15],

[20, 25, 30, 35],

[40, 45, 50, 55]])

原始陣列轉置

in [4]: t = num.t

in [5]: t

out[5]:

array([[ 0, 20, 40],

[ 5, 25, 45],

[10, 30, 50],

[15, 35, 55]])

以 c 風格順序排序

in [6]: c = t.copy(order='c')

in [7]: c

out[7]:

array([[ 0, 20, 40],

[ 5, 25, 45],

[10, 30, 50],

[15, 35, 55]])

in [8]: for x in np.nditer(c):

...: print(x, end=', ')

...:

0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

以 f 風格順序排序

in [9]: f = t.copy(order='f')

in [10]: f

out[10]:

array([[ 0, 20, 40],

[ 5, 25, 45],

[10, 30, 50],

[15, 35, 55]])

in [11]: for x in np.nditer(f):

...: print(x, end=', ')

...:

0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,

強制 nditer 物件使用某種順序排序

原始陣列

in [1]: import numpy as np

in [2]: num = np.arange(0,60,5).reshape(3,4)

in [3]: num

out[3]:

array([[ 0, 5, 10, 15],

[20, 25, 30, 35],

[40, 45, 50, 55]])

以 c 風格順序排序

in [4]: for x in np.nditer(num, order='c'):

...: print(x, end=', ')

...:

0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,

以 f 風格順序排序

in [5]: for x in np.nditer(num, order='f'):

...: print(x, end=', ')

...:

0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

修改陣列中元素的值

nditer 物件有另乙個可選引數 op_flags。 預設情況下,nditer 將視待迭代遍歷的陣列為唯讀物件(read-only),為了在遍歷陣列的同時,實現對陣列元素值得修改,必須指定 read-write 或者 write-only 的模式

in [1]: import numpy as np

in [2]: num = np.arange(0,60,5).reshape(3,4)

in [3]: num

out[3]:

array([[ 0, 5, 10, 15],

[20, 25, 30, 35],

[40, 45, 50, 55]])

in [4]: for x in np.nditer(num, op_flags=['readwrite']):

...: x[...] = 2 * x

...:

in [5]: num

out[5]:

array([[ 0, 10, 20, 30],

[ 40, 50, 60, 70],

[ 80, 90, 100, 110]])

使用外部迴圈

nditer類的構造器擁有flags引數,它可以接受下列值

迭代器遍歷對應於每列,並組合為一維陣列

in [1]: import numpy as np

in [2]: num = np.arange(0,60,5).reshape(3,4)

in [3]: num

out[3]:

array([[ 0, 5, 10, 15],

[20, 25, 30, 35],

[40, 45, 50, 55]])

in [4]: for x in np.nditer(num, flags=['external_loop'], order='f'):

...: print(x, end=', ')

...:

[ 0 40 80], [10 50 90], [ 20 60 100], [ 30 70 110],

廣播迭代

如果兩個陣列是可廣播的,nditer 組合物件能夠同時迭代它們。 假設陣列 a 的維度為 3x4,陣列 b 的維度為 1x4 ,則使用以下迭代器(陣列 b 被廣播到 a 的大小)

in [1]: import numpy as np

in [2]: a = np.arange(0,60,5).reshape(3,4)

in [3]: b = np.array([1,2,3,4], dtype=int)

in [4]: a

out[4]:

array([[ 0, 5, 10, 15],

[20, 25, 30, 35],

[40, 45, 50, 55]])

in [5]: b

out[5]: array([1, 2, 3, 4])

in [6]: for x, y in np.nditer([a, b]):

...: print('%d:%d' % (x,y), end=', ')

...:

0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,

NumPy 教程(第 20 章) 矩陣庫

numpy 中包含了乙個矩陣庫numpy.matlib,該模組中的函式返回的是乙個矩陣,而不是 ndarray 物件 乙個m n的矩陣是乙個由 m 行 row n 列 column 元素排列成的矩形陣列 矩陣裡的元素可以是數字 符號或數學式。以下是乙個由 6 個數字元素構成的 2 行 3 列的矩陣 ...

NumPy 教程(第 7 章) 切片和索引

ndarray 物件中的元素遵循基於零的索引。有三種可用的索引方法型別 字段訪問,基本切片和高階索引 ndarray 物件的內容可以通過索引或切片來訪問和修改,與 python 中 list 的切片操作一樣 ndarray 陣列可以基於 0 n 的下標進行索引,切片物件可以通過內建的 slice 函...

numpy迭代陣列nditer

使用nditer可以完成逐個訪問陣列中的元素。a np.arange 4 reshape 2,2 for i in a print i for i in np.nditer a print i 結果 0 1 2 3 01 23對於一維陣列結果一樣,但是多維就有區別了 nditer物件提供了乙個ord...