1、什麼是Numpy?
Numpy是Python中科學計算的基礎軟體包。
它提供多元數組對象、多種派生對象(如掩碼數組、矩陣)以及用于快速操作數組的函數,包括數學、邏輯、數組形狀變換、排序、選擇、統計運算等等。
Numpy包的核心是
ndarray
對象。
它封裝了python原生的同資料類型的n維數組,為了保證其性能優良,其中許多操作都是在本地編譯後代碼中執行的。
Numpy數組相比python内置序列主要差別如下:
- Numpy數組在建立時固定大小,更改ndarray的大小将建立一個新數組并銷毀原數組;
- Numpy數組元素具有相同資料類型,占用相同記憶體;
- Numpy數組有助于對大量資料高效地完成進階數學運算和其他類型操作;
對于涉及
ndarray
對象的算術、邏輯、位運算等,Numpy預設執行預編譯的C代碼對逐個元素操作,如:
c = a * b
上式中,若a和b是形狀相同的多元數組 ,或是一個标量和一個多元數組,甚至是兩個不同形狀的數組(較小數組可通過某種方式擴充到較大數組),Numpy對其均是逐個元素操作。這說明了Numpy的兩個特征:
矢量化
和
廣播
。矢量化指代碼中無任何顯式的循環、索引等,這些事情在優化的、預編譯的C代碼中完成。廣播指隐式地對元素逐個操作的術語。
2、ndarray介紹
ndarray
對象是Numpy科學工具包的核心,其本質是一個包含具有相同類型和記憶體大小的元素的多元容器。
多元數組的次元和各次元元素的數量由shape屬性指定,數組的元素類型由dtype屬性指定。
Numpy提供多種方法用于多元數組的建立、拼接、拆分等,具體可參考博文《Numpy數組的建立、變形、拼接及拆分》。
Numpy中的多元數組除具有python中其他容器的索引功能之外,還具有更強大的切片、整數數組、布爾數組等索引功能,具體實作可參考相關博文《Numpy數組的索引與切片:取數組的特定行列》。
不同
ndarrays
之間可以共享資料,即一個
ndarray
對象可能是另一個
ndarray
對象的視圖,視圖引用的資料由“base”ndarray處理。
ndarrays
還可以是python所擁有的記憶體視圖或實作buffer或數組接口的對象。
ndarray的常用屬性與方法
屬性 | 功能 |
---|---|
ndarray.ndim | 數組的軸(次元)的個數 |
ndarray.shape | 數組的形狀,元組 |
ndarray.size | 數組元素的總數,等于shape中各元素的乘積 |
ndarray.dtype | 描述數組中元素類型的對象,可使用标準python資料類型建立 |
ndarray.itemsize | 數組中每個元素的位元組大小,如 類型的數組,它等于64/8=8 |
ndarray.data | 該緩沖區包含數組的實際元素,可使用索引替代,一般不直接使用 |
ndarray.strides | 周遊數組時,每個次元上單步執行的步長 |
ndarray.base | 若對象為視圖則傳回原始數組,若資料為其自身所有則傳回None |
ndarray.T | 數組的轉置 |
ndarray.flat | 所有資料的一維疊代器 |
ndarray的轉換方法
屬性 | 功能 |
---|---|
ndarray.item(*args) | 傳回數組指定位置的元素,位置可以是标量或元組 |
ndarray.tolist() | 以清單(可能嵌套)的形式傳回數組 |
ndarray.itemset(*args) | 替換數組指定位置的元素,位置可以是标量或元組 |
ndarray.tostring(order=‘C’) | 傳回數組原始資料的位元組序列 |
ndarray.tofile(fid, sep="", format="%s") | 将數組作為文本或二進制(預設)寫入檔案 |
ndarray.dump(file) | 将數組pickle到指定檔案,對應load指令讀取到記憶體 |
ndarray.dumps() | 以字元串形式傳回數組的pickle,對應loads指定從字元串讀取為ndarry對象 |
ndarray.astype(dtype, order=‘K’, casting=‘unsafe’, subok=True, copy=True) | 傳回數組轉換資料類型後副本 |
ndarray.byteswap(inplace=False) | 交換數組元素的位元組 |
ndarray.copy(order=‘C’) | 傳回數組的副本 |
ndarray.view(dtype=None, type=None) | 傳回數組的視圖 |
ndarray.getfield(dtype, offset=0) | 以某種類型傳回數組的字段 |
ndarray.fill(value) | 用标量值填充數組 |
3、數組運算
數組運算的注意事項:
- 當使用不同類型的數組操作時,結果數組的類型對應于更一般或更精确的數組,即向上轉換,是以不能對低精度的數組元素賦高精度的值;
- 基本的算術、邏輯、位以及比較運算,需要建立新數組,并填充結果;
- 複合運算符,如+=,為就地修改原數組,是以操作符右值不能是高精度的資料;
- 普通乘法運算符
是元素級别運算,若需執行矩陣乘法運算,可使用*
操作符或@
函數;dot
操作符/函數 | 功能 |
---|---|
+ - * / ** >> << > < | & | 算術、邏輯、位以及比較運算符使用元素級别,建立新資料并填充結果 |
+= -= *= /= >>= <<= | 複合運算符,就地修改原數組資料 |
@ dot | 矩陣乘法運算符 |
"""算術、邏輯、位以及比較運算符"""
>>> a = np.array( [20,30,40,50] )
>>> b = np.arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a - b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10*np.sin(a)
array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854])
>>> a < 35
array([ True, True, False, False])
>>> np.array([1,0,2]) & 1
array([1, 0, 0], dtype=int32)
"""複合運算符"""
>>> a = np.ones((2,3), dtype=int)
>>> b = np.random.random((2,3))
>>> a *= 3
>>> a
array([[3, 3, 3],
[3, 3, 3]])
>>> b += a
>>> b
array([[ 3.417022 , 3.72032449, 3.00011437],
[ 3.30233257, 3.14675589, 3.09233859]])
>>> a += b # b is not automatically converted to integer type
Traceback (most recent call last):
...
TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
"""普通乘法運算與矩陣乘法"""
>>> A = np.array([[1,1],[0,1]])
>>> B = np.array([[2,0],[3,4]])
>>> A * B
array([[2, 0],
[0, 4]])
>>> A @ B
array([[5, 4],
[3, 4]])
>>> np.dot(A,B)
array([[5, 4],
[3, 4]])