第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Numpy 遍歷數(shù)組

Numpy 提供了一個(gè)迭代器對(duì)象 numpy.nditer,能夠?qū)崿F(xiàn)靈活地訪問一個(gè)或者多個(gè)數(shù)組元素,達(dá)到遍歷數(shù)組的目的。

1. 數(shù)組元素訪問

1.1 按照內(nèi)存布局打印數(shù)組元素

在默認(rèn)情況下,numpy.nditer 迭代器返回的元素順序,是和數(shù)組內(nèi)存布局一致的,這樣做是為了提升訪問的效率,默認(rèn)是行序優(yōu)先。

案例

例如,我們對(duì)于新創(chuàng)建的 2×3 的數(shù)組,利用 nditer 迭代器進(jìn)行順序訪問:

arr = np.arange(6).reshape(2,3)
arr
Out: 
	array([[0, 1, 2],
           [3, 4, 5]])
for i in np.nditer(arr):
    print(i, end=" ")

打印結(jié)果為:

0 1 2 3 4 5 

可以看到,在不增加其他設(shè)置的情況下,默認(rèn)的打印順序是行序優(yōu)先(即 C-order)。

在不改變內(nèi)部布局的情況下,通過該方式進(jìn)行遍歷,并不會(huì)改變順序,例如我們通過迭代上述數(shù)組的轉(zhuǎn)置來(lái)證明這一點(diǎn)。

for i in np.nditer(arr.T):
    print(i, end=" ")

打印結(jié)果為:

0 1 2 3 4 5 

從上述結(jié)果可以看出,轉(zhuǎn)置方法并未改變數(shù)組元素的存儲(chǔ)順序。

相對(duì)應(yīng)的,我們利用 copy 方法,顯式地更改內(nèi)存順序,nditer 迭代器的遍歷解雇也會(huì)發(fā)生響應(yīng)的變化:

for i in np.nditer(arr.T.copy("C")):
    print(i, end=" ")

打印結(jié)果為:

0 3 1 4 2 5 

1.2 控制遍歷順序

如果想要改變遍歷的順序,一種是上面案例中提到的,利用 copy 方法來(lái)修改內(nèi)存順序。當(dāng)然,nditer 也提供了 order 參數(shù)來(lái)達(dá)到同樣的目的。

案例

C order,即是行序優(yōu)先,跟默認(rèn)的遍歷順序一致。

print ('以 C 風(fēng)格順序排序:')
for i in np.nditer(arr, order="C"):
    print(i, end=" ")

打印結(jié)果為:

以 C 風(fēng)格順序排序:
0 1 2 3 4 5 

Fortran order,即是列序優(yōu)先:

print ('以 F 風(fēng)格順序排序:')
for i in np.nditer(arr, order="F"):
    print(i, end=" ")

打印結(jié)果為:

以 F 風(fēng)格順序排序:
0 3 1 4 2 5 

2. 數(shù)組元素修改

nditer 對(duì)象有另一個(gè)可選參數(shù) op_flags。 默認(rèn)情況下,nditer 將視待迭代遍歷的數(shù)組為只讀對(duì)象(read-only),為了在遍歷數(shù)組的同時(shí),實(shí)現(xiàn)對(duì)數(shù)組元素值得修改,必須指定 read-write 或者 write-only 的模式。

案例

在遍歷的時(shí)候,對(duì)數(shù)組進(jìn)行平方計(jì)算,生成一個(gè)特殊的平方方陣。

arr1 = np.arange(16).reshape(4,4)
arr1
Out:
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15]])
# 指定讀寫模式
for i in np.nditer(arr1, op_flags=["readwrite"]):
    i[...] = i**2
arr1
Out:
    array([[  0,   1,   4,   9],
           [ 16,  25,  36,  49],
           [ 64,  81, 100, 121],
           [144, 169, 196, 225]])

在讀寫模式下,arr1 數(shù)組發(fā)生了變化。

3. flags 可選參數(shù)

flags 參數(shù)可以接受傳入一個(gè)數(shù)組或元組,它可以接受下列值:

參數(shù) 描述
c_index 可以跟蹤 C 順序的索引
f_index 可以跟蹤 Fortran 順序的索引
multi-index 每次迭代可以跟蹤多重索引類型
external_loop 給出的值是具有多個(gè)值的一維數(shù)組,而不是零維數(shù)組

3.1 可以跟蹤 C 順序的索引

list 類似,每個(gè)元素都對(duì)應(yīng)有相應(yīng)的 id。在按照 C 順序跟蹤索引的時(shí)候,數(shù)組的索引可以按照下圖來(lái)直觀理解:
圖片描述

C 順序的索引

上述索引的標(biāo)注是按照行優(yōu)先的順序進(jìn)行的。

案例

設(shè)置 flags=["c_index"],可以實(shí)現(xiàn)類似 list 的 enumerate 函數(shù)的效果:

cit =  np.nditer(arr, flags=["c_index"])
while not cit.finished:
    print("value:", cit[0], "index:<{}>".format(cit.index))
    cit.iternext()

打印結(jié)果為:

value: 0 index:<0>
value: 1 index:<1>
value: 2 index:<2>
value: 3 index:<3>
value: 4 index:<4>
value: 5 index:<5>

在上述代碼中,同過 while 循環(huán)可以逐步打印出每個(gè)元素的值和索引。

3.2 可以跟蹤 Fortran 順序的索引

在按照 F 順序跟蹤索引的時(shí)候,數(shù)組的索引可以按照下圖來(lái)直觀理解:
圖片描述

F 順序的索引

F 順序即列優(yōu)先的順序。

案例

想要實(shí)現(xiàn)該索引順序,可以設(shè)置 flags=["f_index"]

fit =  np.nditer(arr, flags=["f_index"])
while not fit.finished:
    print("value:", fit[0], "index:<{}>".format(fit.index))
    fit.iternext()

打印結(jié)果為:

value: 0 index:<0>
value: 1 index:<2>
value: 2 index:<4>
value: 3 index:<1>
value: 4 index:<3>
value: 5 index:<5>

可以發(fā)現(xiàn),在順序打印該索引結(jié)構(gòu)的時(shí)候,默認(rèn)是按照行優(yōu)先的順序打印的。

也就是說,在打印索引結(jié)構(gòu)的時(shí)候,打印的順序是一樣的,不同的地方在于,c_indexf_index 索引標(biāo)注的順序不一樣。

3.3 多重索引

對(duì)于 arr 這樣的二維數(shù)組,可以用 2 個(gè)維度(x 方向和 y 方向)的序列來(lái)唯一定位每一個(gè)元素,multi-index 則可以打印出該種索引順序。

multi_index 索引類型可以按照下圖來(lái)直觀理解:
圖片描述

multi 順序的索引

案例

設(shè)置 flags=["multi_index"],效果如下:

mul_it = np.nditer(arr, flags=['multi_index'])

while not mul_it.finished:
    print("value:", mul_it[0], "index:<{}>".format(mul_it.multi_index))
    mul_it.iternext()

打印結(jié)果為:

value: 0 index:<(0, 0)>
value: 1 index:<(0, 1)>
value: 2 index:<(0, 2)>
value: 3 index:<(1, 0)>
value: 4 index:<(1, 1)>
value: 5 index:<(1, 2)>

3.4 遍歷返回一維數(shù)組

將一維的最內(nèi)層的循環(huán)轉(zhuǎn)移到外部循環(huán)迭代器,使得 NumPy 的矢量化操作在處理更大規(guī)模數(shù)據(jù)時(shí)變得更有效率。簡(jiǎn)單來(lái)說,當(dāng)指定 flags=['external_loop'] 時(shí),將返回一維數(shù)組而并非單個(gè)元素。

具體來(lái)說,當(dāng) ndarray 的順序和遍歷的順序一致時(shí),將所有元素組成一個(gè)一維數(shù)組返回;當(dāng) ndarray 的順序和遍歷的順序不一致時(shí),返回每次遍歷的一維數(shù)組。

下面通過具體案例來(lái)理解這句話:

案例

對(duì)于上述創(chuàng)建的 arr,是行優(yōu)先順序的數(shù)組。當(dāng)我們指定遍歷順序?yàn)镃(行優(yōu)先,與定義的順序一致),指定 flags=["external_loop"],則有:

for i in np.nditer(arr, flags=['external_loop'], order='C'):
    print(i)

打印結(jié)果為:

[0 1 2 3 4 5]

可以看到,該案例中,把全部元素組成一個(gè)一維數(shù)組,并返回。

案例

當(dāng)我們指定遍歷順序?yàn)镕(列優(yōu)先),指定 flags=["external_loop"],則有:

for i in np.nditer(arr, flags=['external_loop'], order='F'):
    print(i)

打印結(jié)果為:

[0 3]
[1 4]
[2 5]

可以看到,該案例中,返回每次遍歷的一維數(shù)組。

4. 小結(jié)

本節(jié)主要介紹了如何利用 Numpy 內(nèi)置的迭代器對(duì)象 numpy.nditer,實(shí)現(xiàn)靈活地遍歷數(shù)組中的元素。numpy.nditer 迭代器提供了 order 參數(shù),來(lái)控制訪問的順序;提供了 op_flags 參數(shù),來(lái)設(shè)置只讀或讀寫模式;提供 flags 參數(shù)來(lái)同步返回?cái)?shù)組索引,功能非常強(qiáng)大。