《Hello NumPy》系列 | Numpy函數運算

在這裏插入圖片描述

2020,努力做一個無可替代的人!



寫在前面的話

NumPy 第三小節,同學們自行復習第一二小節:

疫情嚴峻,有空多學習,沒事多看看文章,期待陽春三月!

高階部分篇篇都是乾貨,建議大家不要錯過任何一節內容,最好關注我,方便看到每次的文章推送。


正文

前面在創建 NumPy 數組的時候,通過創建方法可以發現有些類似於線性代數,比如創建的正態分佈數組、對角數組等,也確實是這樣,矩陣的一些特性 NumPy 同樣具有。

先來看一下四則運算:

創建維度相同的兩個數組,數組1的值分別爲0-5,數組2是一個全1數組

# 創建 2行3列的二維數組
data_arr1 = np.arange(6).reshape(23)
# 輸出
[[0 1 2]
 [3 4 5]]

# 創建 2行3列的全1數組
data_ones = np.ones((23), 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([12345])
data_yarr = np.array([-1-2-3-4-5])
data_tag = np.array([TrueFalseFalseFalseTrue])

根據布爾數組 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-45]

是不是很麻煩?

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(33)
# 輸出
[[-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>01-1)
# 輸出
[[-1  1  1]
 [ 1  1 -1]
 [-1 -1  1]]

如果要保留小於0的數組值,只替換大於0的值呢?

# 保留小於0的數組值,只替換大於0的值
np.where(data_warr>01, 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(-101010)
# 輸出
[-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([[10-254], [-1-3342]])
# 輸出
[[ 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([23112467-1])
np.unique(data_ints)

# 輸出
[-1  1  2  3  4  6  7]

呼呼,沒騙你吧,這纔是最實用的內容。

總結一下:

說實話,今天的內容挺多的。

總結一下:

  • NumPy 數組的四則運算
  • NumPy 數組的矩陣運算
  • 條件邏輯表述 where
  • 布爾判斷、統計、排序、唯一化

前兩小節屬於運算中比較基礎的內容,知道是什麼、怎麼用就可以了。

重點是後面兩小節,在實際項目中用處很大,建議大家看着例子多讀幾篇。

可以的話,在自己電腦上運行一遍試試

寫在後面的話

透個底,NumPy 系列在我的計劃中還有最後一篇,今天是第三篇。

不知道大家學的怎麼樣,有的內容瞭解就行,也沒必要死磕下去。

當然,我標重點還是建議都掌握啦,下期見!

碎碎念一下

最全的乾貨已經開始了,大家不要掉隊啊。

建議大家關注我,不要錯過高階部分內容!!!


原創不易,歡迎點贊噢

文章首發:公衆號【知秋小夢】

文章同步:掘金,簡書



原文鏈接:《Hello NumPy》系列-運算與函數應用


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章