top
Loading...
NumPy 疊代數組

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=", " ) print ('\n')

輸出結果為:

原始數組是:
[[0 1 2]
 [3 4 5]]

疊代輸出元素:
0, 1, 2, 3, 4, 5, 

以上實例不是使用標准 C 或者 Fortran 順序,選擇的順序是和數組內存布局一致的,這樣做是為了提升訪問的傚率,默認是行序優先(row-major order,或者說是 C-order)。

這反映了默認情況下只需訪問每個元素,而無需考慮其特定順序。我們可以通過疊代上述數組的轉置來看到這一點,併與以 C 順序訪問數組轉置的 copy 方式做對比,如下實例:

實例

import numpy as np a = np.arange(6).reshape(2,3) 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=", " ) print ('\n')

輸出結果為:

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,即是行序優先;

實例

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('原始數組是:') print (a) print ('\n') print ('原始數組的轉置是:') b = a.T print (b) print ('\n') print ('以 C 風格順序排序:') c = b.copy(order='C') print (c) for x in np.nditer(c): print (x, end=", " ) print ('\n') print ('以 F 風格順序排序:') c = b.copy(order='F') print (c) for x in np.nditer(c): print (x, end=", " )

輸出結果為:

原始數組是:
[[ 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 對象使用某種順序:

實例

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('原始數組是:') print (a) print ('\n') print ('以 C 風格順序排序:') for x in np.nditer(a, order = 'C'): print (x, end=", " ) print ('\n') print ('以 F 風格順序排序:') for x in np.nditer(a, order = 'F'): print (x, end=", " )

輸出結果為:

原始數組是:
[[ 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 的模式。

實例

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('原始數組是:') print (a) print ('\n') for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x print ('修改後的數組是:') print (a)

輸出結果為:

原始數組是:
[[ 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 給出的值是具有多個值的一維數組,而不是零維數組

在下面的實例中,疊代器遍歷對應於每列,併組合為一維數組。

實例

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('原始數組是:') print (a) print ('\n') print ('修改後的數組是:') for x in np.nditer(a, flags = ['external_loop'], order = 'F'): print (x, end=", " )

輸出結果為:

原始數組是:
[[ 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 的大小)。

實例

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('第一個數組為:') print (a) print ('\n') print ('第二個數組為:') b = np.array([1, 2, 3, 4], dtype = int) print (b) print ('\n') print ('修改後的數組為:') for x,y in np.nditer([a,b]): print ("%d:%d" % (x,y), end=", " )

輸出結果為:

第一個數組為:
[[ 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,
北斗有巢氏 有巢氏北斗