給妹子講python-S02E01初識NumPy
陪伴學習,一路成長。請一起關注,一起點贊吧!
【要點搶先看】
1.NumPy數據類型的優勢2.ndarray多維數組的創建與基本屬性3.網格數據和範圍數據的創建4.ndarray多維數組的維度轉換與標量計算
【妹子說】那今天我們開篇是不是就要開始接觸NumPy了?
對,首先我們要介紹的就是NumPy這個函數包,NumPy是Numerical Python的簡寫,是高性能科學計算和數據分析的基礎包,他是許多高級工具的構建基礎。
他的核心功能是:
1.多維向量的描述和快速高效計算能力,讓數組和矩陣的使用更加自然;2.大量實用的數學函數,支撐複雜的線性代數、隨機數生成以及傅里葉變換函數3.具備數據的磁碟讀寫工具
【妹子說】我記得之前學習python語言的時候,python的內置容器List似乎也有上述類似功能啊
的確如此,那我們為啥還要另起爐灶呢,原因很簡單,1、編程更簡單;2、計算更快捷。
對於同樣的數值計算任務,使用NumPy要比直接編寫Python代碼便捷的多。這是因為NumPy能夠直接對數組和矩陣進行操作,可以省略很多循環語句,其眾多的數學函數也會讓編寫代碼的工作輕鬆許多。同時底層演算法在設計時有著優異的的性能,NumPy中數組的存儲效率和輸入輸出性能均遠遠優於Python中等價的基本數據結構,如嵌套list
我們首先來看看NumPy中描述N維數組的核心對象,ndarray。
該對象是一個快速而靈活的大數據集容器。
使用NumPy工具需要使用NumPy函數包,因此在程序的起始處需要導入NumPy函數包,並約定俗成的將其簡寫為np
我們先來用python的list對象來創建一個一維ndarray對象:
import numpy as np data = [1,2.11,4,59] arr = np.array(data) print(arr) print(type(arr)) [ 1. 2.11 4. 59. ] <class numpy.ndarray>
當然,這兩種類型的對象是可以相互轉換的,向量到python內置list類型的轉換:
import numpy as np arr = np.arange(8) L = arr.tolist() print(type(L)) print(L) <class list> [0, 1, 2, 3, 4, 5, 6, 7]
再用嵌套列表構建一個ndarray多維數組:
同時,我們還可以獲取這個多維數組的基本屬性:維數、形狀和判定合適的數據類型,如果沒有顯式指定數據類型,np.array在構建數組時會給新建的數組推斷出一個合適的數據類型,這裡依照數據成員8.2,定的數據類型為標準64位浮點類型float64。
import numpy as np data = [[1,2,3,4],[5,6,7,8.2]] arr = np.array(data) print(arr) print(arr.ndim) print(arr.shape) print(arr.dtype) print(type(arr)) [[ 1. 2. 3. 4. ] [ 5. 6. 7. 8.2]] 2 (2, 4) float64 <class numpy.ndarray>
ndim就是數組的維數,
data.ndim = len(data.shape)
當然我們可以對數據類型進行顯式的指定,標準的雙精度浮點數為8位元組,64位,因此該類型在np中記作float64,同理32位整形數記作被記作int32。
不僅在初始化數組時可以指定數據類型,同時可以對已有的ndarray數組進行數據類型的顯式轉換。注意調用astype會創建一個新的數組,即原始數據的一個深拷貝。
import numpy as np arr1 = np.array([1,2,3,4], dtype=np.float64) arr2 = np.array([1,2,3,4], dtype=np.int32) arr3 = arr2.astype(np.float64) print(arr1) print(arr2) print(arr3) [ 1. 2. 3. 4.] [1 2 3 4] [ 1. 2. 3. 4.]
我們看到arr2在創建ndarray數組時,顯式指定了元素類型為int32,後續又通過astype進行數據類型的顯式轉換,創建了新的數組arr3,其數據類型為float64浮點型。
當然還可以創建全0(zeros),全1(ones),及沒有具體值的(未經過初始化的垃圾值)數組(empty),傳入的參數是一個表示形狀的元組:
import numpy as np arr_0 = np.zeros(8) arr_1 = np.ones((3, 8)) arr_e = np.empty((2,3,2)) print(arr_0) print(arr_1) print(arr_e) [ 0. 0. 0. 0. 0. 0. 0. 0.] [[ 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1. 1. 1. 1.]] [[[ 2.05931344e-316 1.87072344e-316] [ 1.85828998e-316 1.98442969e-316] [ 1.85755284e-316 1.70134311e-316]] [[ 1.71304417e-316 2.37875336e-316] [ 1.84704347e-316 1.70132375e-316] [ 2.46176627e-316 2.34552329e-316]]]
同理,之前我們講過python內置函數中有一個range函數,np中也有一個類似的函數實現該功能
import numpy as np arr1 = np.arange(8) print(arr1) print(type(arr1)) [0 1 2 3 4 5 6 7] <class numpy.ndarray>
import numpy as np arr2 = np.arange(0,11,2,dtype=float) print(arr2) [ 0. 2. 4. 6. 8. 10.]
還有一種網格數據的生成方法:即指定起始點和終止點(包含),以及網格點的個數
import numpy as np arr = np.linspace(0,80,5) print(arr) [ 0. 20. 40. 60. 80.]
還有利用eye、identity來創建單位矩陣,後面涉及到線性代數的時候我們再談
最後我們來說說,ndarray數據的維度轉換與最簡單的標量運算。
先談談維度問題,以一個二維數組為例。
我們首先生成一個4×6的二維數組
import numpy as np a = np.arange(24).reshape((6,4)) print(a) [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15] [16 17 18 19] [20 21 22 23]]
然後將其展平,即將其轉化為一個24項的一維數組
import numpy as np a = np.arange(24).reshape((6,4)) print(a.flatten()) [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
還有一種維度轉換的使用場景,如,將之前的6×4的二維數組,轉化為3×8的二維數組
import numpy as np a = np.arange(24).reshape((6,4)) a.resize((3,8)) print(a) [[ 0 1 2 3 4 5 6 7] [ 8 9 10 11 12 13 14 15] [16 17 18 19 20 21 22 23]]
還有線性代數中學過的矩陣的轉置操作,這裡也能做到:
import numpy as np a = np.arange(24).reshape((6,4)) print(a) print(a.transpose()) [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15] [16 17 18 19] [20 21 22 23]] [[ 0 4 8 12 16 20] [ 1 5 9 13 17 21] [ 2 6 10 14 18 22] [ 3 7 11 15 19 23]]
最後我們來看看數組的組合,這種組合操作看上去比較「機械」
首先是水平的組合
import numpy as np a = np.arange(6).reshape((2,3)) b = a * 2 print(a) print(b) print(np.hstack((a,b))) [[0 1 2] [3 4 5]] [[ 0 2 4] [ 6 8 10]] [[ 0 1 2 0 2 4] [ 3 4 5 6 8 10]]
再來看看垂直組合
import numpy as np a = np.arange(6).reshape((2,3)) b = a * 2 print(a) print(b) print(np.vstack((a,b))) [[0 1 2] [3 4 5]] [[ 0 2 4] [ 6 8 10]] [[ 0 1 2] [ 3 4 5] [ 0 2 4] [ 6 8 10]]
最後我們來看看數組的標量計算
其實下面介紹的數組的標量計算功能用傳統的基本數組List類型肯定是都能實現的,但是NumPy提供的最主要的便利之一就是,我們可以像操作原子數據類型一樣對NumPy對象進行操作:不需要顯式循環就可以對它們進行加、減、乘等運算,避免了顯式循環的使用,使得代碼更加清晰。同時,NumPy底層是用C語言實現的,因此代碼運行的也更快。
import numpy as np arr = np.array([[1,2,3],[4,5,6]],dtype=np.float64) print(arr + 1) print(arr ** 2) print(1/arr) [[ 2. 3. 4.] [ 5. 6. 7.]] [[ 1. 4. 9.] [ 16. 25. 36.]] [[ 1. 0.5 0.33333333] [ 0.25 0.2 0.16666667]]
另外還有數組與數組之間的運算,這裡暫時只談論維數相同的數組運算
import numpy as np arr = np.array([[1,2,3],[4,5,6]],dtype=np.float64) print(arr+arr) print(arr*arr) [[ 2. 4. 6.] [ 8. 10. 12.]] [[ 1. 4. 9.] [ 16. 25. 36.]]
對整個向量運用基本數學表達式
import numpy as np arr = np.arange(8) print(np.sin(arr)) [ 0. 0.84147098 0.90929743 0.14112001 -0.7568025 -0.95892427 -0.2794155 0.6569866 ]
【妹子說】這一集看上去就是向我介紹了一個更加高級的數組類型啊。
不完全對,NumPy可不僅限於此,這才剛剛開始。他的功能很好很強大,後面還會一一展開介紹的。
推薦閱讀:
※可以用 Python 來幹些什麼有趣的事?
※如何找到適合需求的 Python 庫?
※Python爬蟲之scrapy從入門到忘記