學習彙總:點這裏
廣播
術語廣播是指 NumPy 在算術運算期間處理不同形狀的數組的能力。 對數組的算術運算通常在相應的元素上進行。 如果兩個陣列具有完全相同的形狀,則這些操作被無縫執行。
>>>import numpy as np
>>>a = np.array([1,2,3,4])
>>>b = np.array([10,20,30,40])
>>>c = a * b
>>>c
array([ 10, 40, 90, 160])
如果兩個數組的維數不相同,則元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以對形狀不相似的數組進行操作,因爲它擁有廣播功能。 較小的數組會廣播到較大數組的大小,以便使它們的形狀可兼容。
如果滿足以下規則,可以進行廣播:
- ndim較小的數組會在前面追加一個長度爲 1 的維度。
- 輸出數組的每個維度的大小是輸入數組該維度大小的最大值。
- 如果輸入在每個維度中的大小與輸出大小匹配,或其值正好爲 1,則在計算中可它。
- 如果輸入的某個維度大小爲 1,則該維度中的第一個數據元素將用於該維度的所有計算。
如果上述規則產生有效結果,並且滿足以下條件之一,那麼數組被稱爲可廣播的。
- 數組擁有相同形狀。
- 數組擁有相同的維數,每個維度擁有相同長度,或者長度爲 1。
- 數組擁有極少的維度,可以在其前面追加長度爲 1 的維度,使上述條件成立。
>>>import numpy as np
>>>a = np.array([[0.0,0.0,0.0],[10.0,10.0,10.0],[20.0,20.0,20.0],[30.0,30.0,30.0]])
>>>b = np.array([1.0,2.0,3.0])
>>>a
array([[ 0., 0., 0.],
[ 10., 10., 10.],
[ 20., 20., 20.],
[ 30., 30., 30.]])
>>>b
array([ 1., 2., 3.])
>>>a + b
array([[ 1., 2., 3.],
[ 11., 12., 13.],
[ 21., 22., 23.],
[ 31., 32., 33.]])
迭代
NumPy 包包含一個迭代器對象numpy.nditer。 它是一個有效的多維迭代器對象,可以用於在數組上進行迭代。 數組的每個元素可使用 Python 的標準Iterator接口來訪問。
1.使用arange()函數創建一個 3X4 數組,並使用nditer對它進行迭代。
>>>import numpy as np
>>>a = np.arange(0,60,5)
>>>a = a.reshape(3,4)
>>>a
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
>>>for x in np.nditer(a):
print (x),
0 5 10 15 20 25 30 35 40 45 50 55
2.迭代的順序匹配數組的內容佈局,而不考慮特定的排序。 這可以通過迭代上述數組的轉置來看到。
>>>import numpy as np
>>>a = np.arange(0,60,5)
>>>a = a.reshape(3,4)
>>>a
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
>>>b = a.T
>>>b
array([[ 0, 20, 40],
[ 5, 25, 45],
[10, 30, 50],
[15, 35, 55]])
>>>for x in np.nditer(b):
print (x),
0 5 10 15 20 25 30 35 40 45 50 55
迭代順序
如果相同元素使用 F 風格順序存儲,則迭代器選擇以更有效的方式對數組進行迭代。
>>>import numpy as np
>>>a = np.arange(0,60,5)
>>>a = a.reshape(3,4)
>>>a
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
>>>b = a.T
>>>b
array([[ 0, 20, 40],
[ 5, 25, 45],
[10, 30, 50],
[15, 35, 55]])
>>>c = b.copy(order='C')
>>>print c
array([[ 0, 20, 40],
[ 5, 25, 45],
[10, 30, 50],
[15, 35, 55]])
>>>for x in np.nditer(c):
print (x),
0 20 40 5 25 45 10 30 50 15 35 55
>>>c = b.copy(order='F')
>>>c
array([[ 0, 20, 40],
[ 5, 25, 45],
[10, 30, 50],
[15, 35, 55]])
>>>for x in np.nditer(c):
print (x),
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)
>>>a
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
>>>for x in np.nditer(a, order = 'C'):
print (x),
0 5 10 15 20 25 30 35 40 45 50 55
>>>for x in np.nditer(a, order = 'F'):
print (x),
0 20 40 5 25 45 10 30 50 15 35 55
修改數組的值
nditer對象有另一個可選參數op_flags。 其默認值爲只讀,但可以設置爲讀寫或只寫模式。 這將允許使用此迭代器修改數組元素。
>>>import numpy as np
>>>a = np.arange(0,60,5)
>>>a = a.reshape(3,4)
>>>a
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
>>>for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
>>>a
array([[ 0, 10, 20, 30],
[ 40, 50, 60, 70],
[ 80, 90, 100, 110]])
外部循環
nditer類的構造器擁有flags參數,它可以接受下列值:
序號 | 參數及描述 |
---|---|
1 | c_index 可以跟蹤 C 順序的索引 |
2 | f_index 可以跟蹤 Fortran 順序的索引 |
3 | multi-index 每次迭代可以跟蹤一種索引類型 |
4 | external_loop 給出的值是具有多個值的一維數組,而不是零維數組 |
迭代器遍歷對應於每列的一維數組。
>>>import numpy as np
>>>a = np.arange(0,60,5)
>>>a = a.reshape(3,4)
>>>a
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
>>>for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print (x),
array([ 0, 20, 40]),
array([ 5, 25, 45]),
array([10, 30, 50]),
array([15, 35, 55]),
廣播迭代
如果兩個數組是可廣播的,nditer組合對象能夠同時迭代它們。 假設數組a具有維度 3X4,並且存在維度爲 1X4 的另一個數組b,則使用以下類型的迭代器(數組b被廣播到a的大小)。
>>>import numpy as np
>>>a = np.arange(0,60,5)
>>>a = a.reshape(3,4)
>>>a
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
>>>b = np.array([1, 2, 3, 4], dtype = int)
>>>b
array([1, 2, 3, 4])
>>>for x,y in np.nditer([a,b]):
print ( "%d:%d" % (x,y)),
0:1 5:2 10:3 15:4 20:1 25:2 30:3 35:4 40:1 45:2 50:3 55:4
字節交換
我們已經知道,存儲在計算機內存中的數據取決於 CPU 使用的架構。 它可以是小端(最小有效位存儲在最小地址中)或大端(最小有效字節存儲在最大地址中)。
numpy.ndarray.byteswap()函數在兩個表示:大端和小端之間切換。
>>>import numpy as np
>>>a = np.array([1, 256, 8755], dtype = np.int16)
>>>a
array([ 1, 256, 8755], dtype=int16)
>>>map(hex,a)
['0x1', '0x100', '0x2233']
# byteswap() 函數通過傳入 true 來原地交換
>>>a.byteswap(True)
array([ 256, 1, 13090], dtype=int16)
# 我們可以看到字節已經交換了
>>>map(hex,a)
['0x100', '0x1', '0x3322']