2020,努力做一個無可替代的人!
寫在前面的話
NumPy 第三小節,同學們自行復習第一二小節:
疫情嚴峻,有空多學習,沒事多看看文章,期待陽春三月!高階部分篇篇都是乾貨
,建議大家不要錯過任何一節內容,最好關注我,方便看到每次的文章推送。
正文
前面在創建 NumPy 數組的時候,通過創建方法可以發現有些類似於線性代數,比如創建的正態分佈數組、對角數組等,也確實是這樣,矩陣的一些特性 NumPy 同樣具有。
先來看一下四則運算:
創建維度相同的兩個數組,數組1的值分別爲0-5,數組2是一個全1數組
# 創建 2行3列的二維數組
data_arr1 = np.arange(6).reshape(2, 3)
# 輸出
[[0 1 2]
[3 4 5]]
# 創建 2行3列的全1數組
data_ones = np.ones((2, 3), dtype=np.int)
# 輸出
[[1 1 1]
[1 1 1]]
ok,數組創建完畢,試着進行計算
# 數組加法運算
data_arr1 + data_ones
# 輸出
[[1 2 3]
[4 5 6]]
# 數組除法運算
data_ones / (data_arr1 + data_ones)
# 輸出
[[1. 0.5 0.33333333]
[0.25 0.2 0.16666667]]
和我們實際進行數組計算的一致,數組之間的任何算術運算都會應用到元素級。
但是,這個前提是兩個數組的維度一致,如果,不一致?或者是個數呢?
看例子:
# 數組與標量的算術運算
data_arr1 * 5
# 輸出
[[ 0 5 10]
[15 20 25]]
同樣,數組與標量的算術運算也會將標量的值傳播到各個元素。
不同大小數組之間的運算叫做廣播。暫且不解釋,我們下節專門說它。
再來看下矩陣運算
在線性代數中,有矩陣轉置,在 NumPy 中,也就有了數組轉置。
轉置(transpose)是一種數組維度重塑的一種特殊形式,它返回的是源數據的視圖。
數組不僅有 transpose 方法,還有一個特殊的 T 屬性。
data_arr1
# 輸出
[[0 1 2]
[3 4 5]]
# 轉置操作的兩種實現方法
data_arr1.T
data_arr1.transpose()
# 輸出
[[0 3]
[1 4]
[2 5]]
在進行矩陣運算時,比如我們需要計算矩陣內積:X[T]X,可以使用 np.dot 計算
根據公式:矩陣內積 = X 的轉置乘以 X
# 創建數組
data_arr2 = np.random.randn(1,3)
# 輸出
[[-0.14205835 -1.43319166 0.8389062 ]]
# 計算矩陣內積
np.dot(data_arr2.T, data_arr2)
# 輸出
[[ 0.02018058 0.20359685 -0.11917363]
[ 0.20359685 2.05403832 -1.20231337]
[-0.11917363 -1.20231337 0.70376361]]
還有高維數組的轉置這些,實際上並不常用,而且也不是很好理解,就不再提了,最常用的就是二維數組的轉置,會這個就可。
列舉部分線性代數在 NumPy 的實現
函數 | 說明 |
---|---|
dot | 矩陣乘法 |
trace | 計算對角線元素的和 |
det | 計算矩陣行列式 |
inv | 計算方陣的逆 |
solve | 解線性方程組 Ax = b,其中 A 爲一個方陣 |
lstsq | 計算 Ax = b 的最小二乘解 |
…… | …… |
通用函數
通用函數(即 ufunc)是一種對 ndarray 中的數據執行元素級運算的函數。
你可以將其看做簡單函數的矢量化包裝器:接受一個或多個標量值,併產生一個或多個標量值。
先來看看一元通用函數(unary ufunc)
# 創建數組
data_unary = np.arange(10)
# 輸出
[0 1 2 3 4 5 6 7 8 9]
# 求數組每個元素的平方根
np.sqrt(data_unary)
# 輸出
[0. 1. 1.41421356 1.73205081 2. 2.23606798
2.44948974 2.64575131 2.82842712 3. ]
# 求數組的最大最小值
np.min(data_unary)
np.max(data_unary)
# 輸出
0
9
就和 Python 的常規語法一樣,NumPy 通用函數也是直接調用即可。
另外還有一些接受2個數組,返回一個結果數組的通用函數(二元函數)
列舉一些常用的一元和二元函數
函數 | 說明 | |
---|---|---|
一元函數 | abs | 計算整數、浮點數或負數的絕對值。 |
一元函數 | sqrt | 計算個元素的平方根 |
一元函數 | square | 計算各元素的平凡 |
一元函數 | exp | 計算各元素的指數 |
一元函數 | log、log10、log2 | 分別爲底數爲e的log、底數爲10的log、底數爲2的log |
一元函數 | sign | 計算各元素的正負號 |
一元函數 | ceil | 計算各元素的ceiling值(大於等於該值的最小整數) |
一元函數 | floor | 計算各元素的floor值(小於等於該值的最大整數) |
一元函數 | cos、cosh、sin、sinh、tan、tanh | 普通和雙曲線三角函數 |
一元函數 | isnan | 返回一個數組表示”哪些是NaN“的布爾型數組 |
…… | …… | …… |
二元函數 | add | 將數組中對應的元素相加 |
二元函數 | sutract | 從第一個數組中減去第二個數組中的元素 |
二元函數 | multiply | 數組元素相乘 |
二元函數 | divide | 數組元素相除 |
二元函數 | power | 計算 A 的 B 次方 |
…… | …… | …… |
是不是以爲到這就結束了?
沒錯,快結束了,但是我總覺得下面的內容纔是今天的重點內容
,信不信由你。
條件邏輯表述
我們都知道 Python 中的三元表達式: x if condition else y
那如果我們有兩個值數組分別表示 x 和 y,有一個布爾數組表示 condition,如何進行條件邏輯表述呢?
# 創建數組
data_xarr = np.array([1, 2, 3, 4, 5])
data_yarr = np.array([-1, -2, -3, -4, -5])
data_tag = np.array([True, False, False, False, True])
根據布爾數組 data_tag 選取 data_xarr 和 data_yarr 的值:當 data_tag 爲 True,選擇 data_xarr 的值,否則從 data_yarr 中選取。
先來看一下列表推導式:
# 實現三元表達式功能
result = [(x if tag else y)
for x, y, tag in zip(data_xarr, data_yarr, data_tag)
]
# 輸出
[1, -2, -3, -4, 5]
是不是很麻煩?
NumPy 中一個函數就可以實現上面的功能!!!
# 使用 where 函數實現三元表達式功能
result = np.where(data_tag, data_xarr, data_yarr)
# 輸出
[ 1 -2 -3 -4 5]
是不是很方便?
解釋一下 where 函數的用法:第一個參數是條件 condition,第二和第三個參數相當於三元表達式中的 x 和 y
。其中 x 和 y 不必是數組,也可以是標量值, where 函數返回一個新的數組。
例如,通過 where 函數進行數據清洗,大於0的數全部置爲1,小於0的數全部置爲-1
# 創建 3*3 的數組
data_warr = np.random.randn(3, 3)
# 輸出
[[-0.57519374 0.91571952 0.2104197 ]
[ 0.32693672 0.95512399 -0.09581747]
[-1.40553911 -0.96782964 0.73291699]]
# 大於0的數全部置爲1,小於0的數全部置爲-1
result = np.where(data_warr>0, 1, -1)
# 輸出
[[-1 1 1]
[ 1 1 -1]
[-1 -1 1]]
如果要保留小於0的數組值,只替換大於0的值呢?
# 保留小於0的數組值,只替換大於0的值
np.where(data_warr>0, 1, data_warr)
# 輸出
[[-0.57519374 1. 1. ]
[ 1. 1. -0.09581747]
[-1.40553911 -0.96782964 1. ]]
比 where 更重要的內容
布爾判斷+統計
,你沒聽錯,數據分析常用噢
舉例:隨機數中所有大於0的數的和、平均值、標準差方差等
# 創建10個範圍在-10~10的隨機整數
data_rn = np.random.randint(-10, 10, 10)
# 輸出
[-9 -2 -1 -7 9 9 -4 6 3 -1]
# 大於0的所有數的和、平均值、標準差方差
(data_rn>0).sum()
(data_rn>0).mean()
(data_rn>0).std()
(data_rn>0).var()
# 輸出
4
0.4
0.48989794855663565
0.24000000000000005
any、how 檢測
any 用於測試數組中是否存在一個或多個 True
all 用於檢查數組中所有值是否都是 True
sort 排序
和 Python 內置的列表類型一樣,NumPy 數組也可以通過 sort 方法進行排序
data_sort = np.array([[1, 0, -2, 5, 4], [-1, -3, 3, 4, 2]])
# 輸出
[[ 1 0 -2 5 4]
[-1 -3 3 4 2]]
# 默認排序(行)
data_sort.sort()
# 輸出
[[-2 0 1 4 5]
[-3 -1 2 3 4]]
# 在0軸上排序(列)
data_sort.sort(axis=0)
# 輸出
[[-3 -1 1 3 4]
[-2 0 2 4 5]]
unique 唯一化
針對一維數組最常用的基本集合運算:unique 用於找出數組中的唯一值並返回已排序的結果
# `unique 找出數組中的唯一值並返回已排序的結果`
data_ints = np.array([2, 3, 1, 1, 2, 4, 6, 7, -1])
np.unique(data_ints)
# 輸出
[-1 1 2 3 4 6 7]
呼呼,沒騙你吧,這纔是最實用的內容。
總結一下:
說實話,今天的內容挺多的。
總結一下:
- NumPy 數組的四則運算
- NumPy 數組的矩陣運算
- 條件邏輯表述 where
- 布爾判斷、統計、排序、唯一化
前兩小節屬於運算中比較基礎的內容,知道是什麼、怎麼用就可以了。
重點是後面兩小節,在實際項目中用處很大,建議大家看着例子多讀幾篇。
可以的話,在自己電腦上運行一遍試試
寫在後面的話
透個底,NumPy 系列在我的計劃中還有最後一篇,今天是第三篇。
不知道大家學的怎麼樣,有的內容瞭解就行,也沒必要死磕下去。
當然,我標重點還是建議都掌握啦,下期見!
碎碎念一下
最全的乾貨已經開始了,大家不要掉隊啊。
建議大家關注我,不要錯過高階部分內容!!!
原創不易,歡迎點贊噢
文章首發:公衆號【知秋小夢】
文章同步:掘金,簡書