NumPy 迭代數組
NumPy 迭代器對象 numpy.nditer 提供了一種靈活訪問一個或者多個數組元素的方式。
迭代器最基本的任務的可以完成對數組元素的訪問。
接下來我們使用 arange() 函數創建一個 2X3 數組,並使用 nditer 對它進行迭代。
實例
輸出結果為:
原始數組是: [[0 1 2] [3 4 5]] 迭代輸出元素: 0, 1, 2, 3, 4, 5,
以上實例不是使用標準 C 或者 Fortran 順序,選擇的順序是和數組記憶體佈局一致的,這樣做是為了提升訪問的效率,默認是行序優先(row-major order,或者說是 C-order)。
這反映了默認情況下只需訪問每個元素,而無需考慮其特定順序。我們可以通過迭代上述數組的轉置來看到這一點,並與以 C 順序訪問數組轉置的 copy 方式做對比,如下實例:
實例
輸出結果為:
0, 1, 2, 3, 4, 5, 0, 3, 1, 4, 2, 5,
從上述例子可以看出,a 和 a.T 的遍曆順序是一樣的,也就是他們在內存中的存儲順序也是一樣的,但是 a.T.copy(order = 'C') 的遍曆結果是不同的,那是因為它和前兩種的存儲方式是不一樣的,默認是按行訪問。
控制遍曆順序
for x in np.nditer(a, order='F'):
Fortran order,即是列序優先;for x in np.nditer(a.T, order='C'):
C order,即是行序優先;
實例
輸出結果為:
原始數組是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 原始數組的轉置是: [[ 0 20 40] [ 5 25 45] [10 30 50] [15 35 55]] 以 C 風格順序排序: [[ 0 20 40] [ 5 25 45] [10 30 50] [15 35 55]] 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 以 F 風格順序排序: [[ 0 20 40] [ 5 25 45] [10 30 50] [15 35 55]] 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,
可以通過顯式設置,來強制 nditer 對象使用某種順序:
實例
輸出結果為:
原始數組是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 以 C 風格順序排序: 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 以 F 風格順序排序: 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,
修改數組中元素的值
nditer 對象有另一個可選參數 op_flags。 默認情況下,nditer 將視待迭代遍曆的數組為只讀對象(read-only),為了在遍歷數組的同時,實現對數組元素值得修改,必須指定 read-write 或者 write-only 的模式。
實例
輸出結果為:
原始數組是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 修改後的數組是: [[ 0 10 20 30] [ 40 50 60 70] [ 80 90 100 110]]
使用外部迴圈
nditer類的構造器擁有flags參數,它可以接受下列值:
參數 | 描述 |
---|---|
c_index |
可以跟蹤 C 順序的索引 |
f_index |
可以跟蹤 Fortran 順序的索引 |
multi-index |
每次迭代可以跟蹤一種索引類型 |
external_loop |
給出的值是具有多個值的一維數組,而不是零維數組 |
在下面的實例中,迭代器遍曆對應於每列,並組合為一維數組。
實例
輸出結果為:
原始數組是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 修改後的數組是: [ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],
廣播迭代
如果兩個數組是可廣播的,nditer 組合對象能夠同時迭代它們。 假設數組 a 的維度為 3X4,數組 b 的維度為 1X4 ,則使用以下迭代器(數組 b 被廣播到 a 的大小)。
實例
輸出結果為:
第一個數組為: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 第二個數組為: [1 2 3 4] 修改後的數組為: 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,