NumPy 迭代器對(duì)象 numpy.nditer 提供了一種靈活訪問(wèn)一個(gè)或者多個(gè)數(shù)組元素的方式。
迭代器最基本的任務(wù)的可以完成對(duì)數(shù)組元素的訪問(wèn)。
接下來(lái)我們使用 arange() 函數(shù)創(chuàng)建一個(gè) 2X3 數(shù)組,并使用 nditer 對(duì)它進(jìn)行迭代。
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
以上實(shí)例不是使用標(biāo)準(zhǔn) C 或者 Fortran 順序,選擇的順序是和數(shù)組內(nèi)存布局一致的,這樣做是為了提升訪問(wèn)的效率,默認(rèn)是行序優(yōu)先(row-major order,或者說(shuō)是 C-order)。
這反映了默認(rèn)情況下只需訪問(wèn)每個(gè)元素,而無(wú)需考慮其特定順序。我們可以通過(guò)迭代上述數(shù)組的轉(zhuǎn)置來(lái)看到這一點(diǎn),并與以 C 順序訪問(wèn)數(shù)組轉(zhuǎn)置的 copy 方式做對(duì)比,如下實(shí)例:
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
從上述實(shí)例可以看出,a 和 a.T 的遍歷順序是一樣的,也就是他們?cè)趦?nèi)存中的存儲(chǔ)順序也是一樣的,但是 a.T.copy(order = 'C') 的遍歷結(jié)果是不同的,那是因?yàn)樗颓皟煞N的存儲(chǔ)方式是不一樣的,默認(rèn)是按行訪問(wèn)。
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
可以通過(guò)顯式設(shè)置,來(lái)強(qiáng)制 nditer 對(duì)象使用某種順序:
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 對(duì)象有另一個(gè)可選參數(shù) op_flags。 默認(rèn)情況下,nditer 將視待迭代遍歷的數(shù)組為只讀對(duì)象(read-only),為了在遍歷數(shù)組的同時(shí),實(shí)現(xiàn)對(duì)數(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 | 給出的值是具有多個(gè)值的一維數(shù)組,而不是零維數(shù)組 |
在下面的實(shí)例中,迭代器遍歷對(duì)應(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]
如果兩個(gè)數(shù)組是可廣播的,nditer 組合對(duì)象能夠同時(shí)迭代它們。 假設(shè)數(shù)組 a 的維度為 3X4,數(shù)組 b 的維度為 1X4 ,則使用以下迭代器(數(shù)組 b 被廣播到 a 的大?。?/p>
import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('第一個(gè)數(shù)組為:') print (a) print ('\n') print ('第二個(gè)數(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é)果為:
第一個(gè)數(shù)組為: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 第二個(gè)數(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,