NumPy 迭代器對象 numpy.nditer 提供了一種靈活訪問一個或者多個數(shù)組元素的方式。
迭代器最基本的任務(wù)的可以完成對數(shù)組元素的訪問。
接下來我們使用 arange() 函數(shù)創(chuàng)建一個 2X3 數(shù)組,并使用 nditer 對它進行迭代。
import numpy as np a = np.arange(12).reshape(2,6) print ('原始數(shù)組是:') print (a) print ('\n') print ('迭代輸出元素:') for x in np.nditer(a): print (x, end=" " )
輸出結(jié)果為:
原始數(shù)組如下: [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]] 迭代輸出數(shù)組元素如下: 0 1 2 3 4 5 6 7 8 9 10 11
以上實例不是使用標準 C 或者 Fortran 順序,選擇的順序是和數(shù)組內(nèi)存布局一致的,這樣做是為了提升訪問的效率,默認是行序優(yōu)先(row-major order,或者說是 C-order)。
這反映了默認情況下只需訪問每個元素,而無需考慮其特定順序。我們可以通過迭代上述數(shù)組的轉(zhuǎn)置來看到這一點,并與以 C 順序訪問數(shù)組轉(zhuǎn)置的 copy 方式做對比,如下實例:
import numpy as np a = np.arange(12).reshape(2,6) for x in np.nditer(a.T): print (x, end=" " ) print ('\n') for x in np.nditer(a.T.copy(order='C')): print (x, end=" " )
輸出結(jié)果為:
0 1 2 3 4 5 6 7 8 9 10 11 0 6 1 7 2 8 3 9 4 10 5 11
從上述實例可以看出,a 和 a.T 的遍歷順序是一樣的,也就是他們在內(nèi)存中的存儲順序也是一樣的,但是 a.T.copy(order = 'C') 的遍歷結(jié)果是不同的,那是因為它和前兩種的存儲方式是不一樣的,默認是按行訪問。
for x in np.nditer(a, order='F'):Fortran order,即是列序優(yōu)先;for x in np.nditer(a.T, order='C'):C order,即是行序優(yōu)先;
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print ('原始數(shù)組是:') print (a) print ('\n') print ('原始數(shù)組的轉(zhuǎn)置是:') b = a.T print (b) print ('\n') print ('以 C 風(fēng)格順序排序:') c = b.copy(order='C') print (c) for x in np.nditer(c): print (x, end=" " ) print ('\n') print ('以 F 風(fēng)格順序排序:') c = b.copy(order='F') print (c) for x in np.nditer(c): print (x, end=" " )
輸出結(jié)果為:
原始數(shù)組是: [[ 0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95]] 原始數(shù)組的轉(zhuǎn)置是: [[ 0 25 50 75] [ 5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95]] 以 C 風(fēng)格順序排序: [[ 0 25 50 75] [ 5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95]] 0 25 50 75 5 30 55 80 10 35 60 85 15 40 65 90 20 45 70 95 以 F 風(fēng)格順序排序: [[ 0 25 50 75] [ 5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95]] 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95
可以通過顯式設(shè)置,來強制 nditer 對象使用某種順序:
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print ('原始數(shù)組是:') print (a) print ('\n') print ('以 C 風(fēng)格順序排序:') for x in np.nditer(a, order = 'C'): print (x, end=", " ) print ('\n') print ('以 F 風(fēng)格順序排序:') for x in np.nditer(a, order = 'F'): print (x, end=" " )
輸出結(jié)果為:
原始數(shù)組是: [[ 0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95]] 以 C 風(fēng)格順序排序: 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 以 F 風(fēng)格順序排序: 0 25 50 75 5 30 55 80 10 35 60 85 15 40 65 90 20 45 70 95
nditer 對象有另一個可選參數(shù) op_flags。 默認情況下,nditer 將視待迭代遍歷的數(shù)組為只讀對象(read-only),為了在遍歷數(shù)組的同時,實現(xiàn)對數(shù)組元素值得修改,必須指定 read-write 或者 write-only 的模式。
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print ('原始數(shù)組是:') print (a) print ('\n') for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x print ('修改后的數(shù)組是:') print (a)
輸出結(jié)果為:
原始數(shù)組是: [[ 0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95]] 修改后的數(shù)組是: [[ 0 10 20 30 40] [ 50 60 70 80 90] [100 110 120 130 140] [150 160 170 180 190]]
nditer類的構(gòu)造器擁有flags參數(shù),它可以接受下列值:
參數(shù) | 描述 |
c_index | 可以跟蹤 C 順序的索引 |
f_index | 可以跟蹤 Fortran 順序的索引 |
multi-index | 每次迭代可以跟蹤一種索引類型 |
external_loop | 給出的值是具有多個值的一維數(shù)組,而不是零維數(shù)組 |
在下面的實例中,迭代器遍歷對應(yīng)于每列,并組合為一維數(shù)組。
import numpy as np a = np.arange(0,100,5) a = a.reshape(4,5) print ('原始數(shù)組是:') print (a) print ('\n') print ('修改后的數(shù)組是:') for x in np.nditer(a, flags = ['external_loop'], order = 'F'): print (x, end=" " )
輸出結(jié)果為:
原始數(shù)組是: [[ 0 5 10 15 20] [25 30 35 40 45] [50 55 60 65 70] [75 80 85 90 95]] 修改后的數(shù)組是: [ 0 25 50 75] [ 5 30 55 80] [10 35 60 85] [15 40 65 90] [20 45 70 95]
如果兩個數(shù)組是可廣播的,nditer 組合對象能夠同時迭代它們。 假設(shè)數(shù)組 a 的維度為 3X4,數(shù)組 b 的維度為 1X4 ,則使用以下迭代器(數(shù)組 b 被廣播到 a 的大小)。
import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('第一個數(shù)組為:') print (a) print ('\n') print ('第二個數(shù)組為:') b = np.array([1, 2, 3, 4], dtype = int) print (b) print ('\n') print ('修改后的數(shù)組為:') for x,y in np.nditer([a,b]): print ("%d:%d" % (x,y), end=" " )
輸出結(jié)果為:
第一個數(shù)組為: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 第二個數(shù)組為: [1 2 3 4] 修改后的數(shù)組為: 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,