天天看點

NumPy 疊代數組

NumPy 疊代器對象 numpy.nditer 提供了一種靈活通路一個或者多個數組元素的方式。

疊代器最基本的任務的可以完成對數組元素的通路。

接下來我們使用 arange() 函數建立一個 2X3 數組,并使用 nditer 對它進行疊代。

import numpy as np

a = np.arange(6).reshape(2,3)

print ('原始數組是:')

print (a)

print ('\n')

print ('疊代輸出元素:')

for x in np.nditer(a):

print (x, end=", " )

輸出結果為:

以上執行個體不是使用标準 C 或者 Fortran 順序,選擇的順序是和數組記憶體布局一緻的,這樣做是為了提升通路的效率,預設是行序優先(row-major order,或者說是 C-order)。

這反映了預設情況下隻需通路每個元素,而無需考慮其特定順序。我們可以通過疊代上述數組的轉置來看到這一點,并與以 C 順序通路數組轉置的 copy 方式做對比,如下執行個體:

for x in np.nditer(a.T):

for x in np.nditer(a.T.copy(order='C')):

從上述例子可以看出,a 和 a.T 的周遊順序是一樣的,也就是他們在記憶體中的存儲順序也是一樣的,但是 a.T.copy(order = 'C') 的周遊結果是不同的,那是因為它和前兩種的存儲方式是不一樣的,預設是按行通路。

<code>for x in np.nditer(a, order='F'):</code>Fortran order,即是列序優先;

<code>for x in np.nditer(a.T, order='C'):</code>C order,即是行序優先;

a = np.arange(0,60,5)

a = a.reshape(3,4)

print ('原始數組的轉置是:')

b = a.T

print (b)

print ('以 C 風格順序排序:')

c = b.copy(order='C')

print (c)

for x in np.nditer(c):

print ('\n')

print ('以 F 風格順序排序:')

c = b.copy(order='F')

可以通過顯式設定,來強制 nditer 對象使用某種順序:

for x in np.nditer(a, order = 'C'):

print ('以 F 風格順序排序:')

for x in np.nditer(a, order = 'F'):

nditer 對象有另一個可選參數 op_flags。 預設情況下,nditer 将視待疊代周遊的數組為隻讀對象(read-only),為了在周遊數組的同時,實作對數組元素值得修改,必須指定 read-write 或者 write-only 的模式。

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

x[...]=2*x

print ('修改後的數組是:')

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

參數

描述

<code>c_index</code>

可以跟蹤 C 順序的索引

<code>f_index</code>

可以跟蹤 Fortran 順序的索引

<code>multi_index</code>

每次疊代可以跟蹤一種索引類型

<code>external_loop</code>

給出的值是具有多個值的一維數組,而不是零維數組

在下面的執行個體中,疊代器周遊對應于每列,并組合為一維數組。

for x in np.nditer(a, flags = ['external_loop'], order = 'F'):

如果兩個數組是可廣播的,nditer 組合對象能夠同時疊代它們。 假設數組 a 的次元為 3X4,數組 b 的次元為 1X4 ,則使用以下疊代器(數組 b 被廣播到 a 的大小)。

print ('第一個數組為:')

print ('第二個數組為:')

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

print ('修改後的數組為:')

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

print ("%d:%d" % (x,y), end=", " )