作者:韓信子@ShowMeAI
教程地址:http://www.showmeai.tech/tutorials/33
本文地址:http://www.showmeai.tech/article-detail/142
宣告:版權所有,轉載請聯絡平臺與作者並註明出處
n維陣列是NumPy的核心概念,大部分資料的操作都是基於n維陣列完成的。本系列內容覆蓋到1維陣列操作、2維陣列操作、3維陣列操作方法,本篇講解Numpy與1維陣列操作。
一、向量初始化
可以通過Python列表建立NumPy陣列。
如圖中(a),將列表元素轉化為一維陣列。注意,這裡一般會確保列表元素型別相同,否則預設dtype=’object'
,會影響後續運算,甚至產生語法錯誤。
由於在陣列末尾沒有預留空間以快速新增新元素,NumPy陣列無法像Python列表那樣增長。因此,通常的處理方式包括:
- 在變長Python列表中準備好資料,然後將其轉換為NumPy陣列
- 使用
np.zeros
或np.empty
預先分配必要的空間(圖中b)
通過圖中(c)方法,可以建立一個與某一變數形狀一致的空陣列。
不止是空陣列,通過上述方法還可以將陣列填充為特定值:
在NumPy中,還可以通過單調序列初始化陣列:
如果我們需要浮點陣列,可以使用 arange(3).astype(float)
這樣的操作更改arange輸出的型別,也可以在引數端使用浮點數,比如 arange(4.)
來生產浮點數Numpy陣列。
以下是arange浮點型別資料可能出現的一些問題及解決方案:
圖中,0.1對我們來說是一個有限的十進位制數,但對計算機而言,它是一個二進位制無窮小數,必須四捨五入為一個近似值。因此,將小數作為arange的步長可能導致一些錯誤。可以通過以下兩種方式避免如上錯誤:
- 使間隔末尾落入非整數步數,但這會降低可讀性和可維護性;
- 使用linspace,這樣可以避免四捨五入的錯誤影響,並始終生成要求數量的元素。
- 使用linspace時尤其需要注意最後一個的數量引數設定,由於它計算點數量,而不是間隔數量,因此上圖中數量引數是11,而不是10。
隨機陣列的生成方法如下:
二、向量索引
NumPy可以使用非常直接的方式對陣列資料進行訪問:
圖中,除“fancy indexing”外,其他所有索引方法本質上都是views:它們並不儲存資料,如果原陣列在被索引後發生更改,則會反映出原始陣列中的更改。
上述所有這些方法都可以改變原始陣列,即允許通過分配新值改變原陣列的內容。這導致無法通過切片來複制陣列。如下是python列表和NumPy陣列的對比:
NumPy陣列支援通過布林索引獲取資料,結合各種邏輯運算子可以有很高階的資料選擇方式,這在Python列表中是不具備的:
注意,不可以使用3 <= a <= 5這樣的Python“三元”比較。
如上所述,布林索引是可寫的。如下圖 np.where
和 np.clip
兩個專有函式。
三、向量操作
NumPy支援快速計算,向量運算操作接近C++速度級別,並不受Python迴圈本身計算慢的限制。NumPy允許像普通數字一樣操作整個陣列:
在python中,a//b表示a div b(除法的商),x**n表示 xⁿ
浮點數的計算也是如此,NumPy能夠將標量廣播到陣列:
Numpy提供了許多數學函式來處理向量:
向量點乘(內積)和叉乘(外積、向量積)如下:
NumPy也提供瞭如下三角函式運算:
陣列整體進行四捨五入:
floor向上取整,ceil向下取整,round四捨五入
np.around
與 np.round
是等效的,這樣做只是為了避免 from numpy import *
時與Python around
的衝突(但一般的使用方式是import numpy as np)。當然,你也可以使用a.round()。
NumPy還可以實現以下功能:
以上功能都存在相應的nan-resistant變體:例如nansum
,nanmax
等
在NumPy中,排序函式功能有所閹割:
對於一維陣列,可以通過反轉結果來解決reversed函式缺失的不足,但在2維陣列中該問題變得棘手。
四、查詢向量中的元素
NumPy陣列並沒有Python列表中的索引方法,索引資料的對比如下:
index()中的方括號表示 j 或 i&j 可以省略
- 可以通過
np.where(a==x)[0] [0]
查詢元素,但這種方法很不pythonic,哪怕需要查詢的項在陣列開頭,該方法也需要遍歷整個陣列。 - 使用Numba實現加速查詢,
next((i[0] for i, v in np.ndenumerate(a) if v==x), -1)
,在最壞的情況下,它的速度要比where慢。 - 如果陣列是排好序的,使用
v = np.searchsorted(a, x)
;return v if a[v]==x else -1
時間複雜度為O(log N)
,但在這之前,排序的時間複雜度為O(N log N)。
實際上,通過C實現加速搜尋並不是困難,問題是浮點資料比較。
五、浮點數比較
np.allclose(a, b)
用於容忍誤差之內的浮點數比較。
np.allclose
假定所有比較數字的尺度為1。如果在納秒級別上,則需要將預設atol引數除以1e9:np.allclose(1e-9,2e-9, atol=1e-17)==False
。math.isclose
不對要比較的數字做任何假設,而是需要使用者提供一個合理的abs_tol值(np.allclose
預設的atol值1e-8足以滿足小數位數為1的浮點數比較,即math.isclose(0.1+0.2–0.3, abs_tol=1e-8)==True
。
此外,對於絕隊偏差和相對偏差,np.allclose依然存在一些問題。例如,對於某些值a、b, allclose(a,b)!=allclose(b,a),而在math.isclose
中則不存在這些問題。檢視GitHub上的浮點資料指南和相應的NumPy問題了解更多資訊。
資料與程式碼下載
本教程系列的程式碼可以在ShowMeAI對應的github中下載,可本地python環境執行,能訪問Google的寶寶也可以直接藉助google colab一鍵執行與互動操作學習哦!
本系列教程涉及的速查表可以在以下地址下載獲取:
擴充參考資料
ShowMeAI相關文章推薦
- 資料分析介紹
- 資料分析思維
- 資料分析的數學基礎
- 業務認知與資料初探
- 資料清洗與預處理
- 業務分析與資料探勘
- 資料分析工具地圖
- 統計與資料科學計算工具庫Numpy介紹
- Numpy與1維陣列操作
- Numpy與2維陣列操作
- Numpy與高維陣列操作
- 資料分析工具庫Pandas介紹
- 圖解Pandas核心操作函式大全
- 圖解Pandas資料變換高階函式
- Pandas資料分組與操作
- 資料視覺化原則與方法
- 基於Pandas的資料視覺化
- seaborn工具與資料視覺化