NumPy 學習筆記
NumPy 是一個 Python 庫。
NumPy 用於處理陣列。
NumPy 是“Numerical Python”的縮寫。
建立一個 NumPy 陣列:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))
輸出:
[1 2 3 4 5]
<class 'numpy.ndarray'>
NumPy 介紹
在 Python 中,我們有用於陣列目的的列表,但它們的處理速度很慢。
NumPy 旨在提供比傳統的 Python 快的列表。
NumPy 中的陣列物件稱為ndarray, 它提供了許多支援功能,使使用變得非常容易。
陣列在資料科學中非常頻繁地使用,其中速度和資源 都非常重要。
資料科學:是電腦科學的一個分支,我們研究如何儲存、使用和分析資料以從中獲取資訊。
與列表不同,NumPy 陣列儲存在記憶體中的一個連續位置,因此程序可以非常有效地訪問和操作它們。
這種行為在電腦科學中稱為參考區域性性。
這就是 NumPy 比傳統python列表更快的主要原因。此外,它還經過最佳化,可與最新的 CPU 架構配合使用。
NumPy是一個Python庫,部分是用Python編寫的,但大多數需要快速計算的部分都是用C或C++編寫的。
NumPy 的原始碼位於此 github 儲存庫 Numpy
NumPy 入門
pip install numpy
安裝numpy
匯入 NumPy
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
NumPy 建立陣列
可以將列表、元組或任何類似陣列的物件傳遞到方法中,它將被轉換為:ndarray
arr = np.array((1, 2, 3, 4, 5))
arr = np.array([1, 2, 3, 4, 5])
建立一個值為 42 的 0-D 陣列:
arr = np.array(42)
建立一個包含值 1、2、3、4、5 的 1-D 陣列:
arr = np.array([1, 2, 3, 4, 5])
建立一個包含兩個陣列的 2-D 陣列,其值分別為 1,2,3 和 4,5,6:
arr = np.array([[1, 2, 3], [4, 5, 6]])
建立一個具有兩個二維陣列的三維陣列:
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])
檢查陣列有多少個維度:
arr.ndim
陣列可以具有任意數量的維度。
建立一個具有 5 個維度的陣列,並驗證它是否具有 5 個維度:
arr = np.array([1, 2, 3, 4], ndmin=5)
print(arr)
print('number of dimensions :', arr.ndim)
[[[[[1 2 3 4]]]]]
number of dimensions : 5
NumPy 陣列索引
從以下陣列中獲取第一個元素:
arr = np.array([1, 2, 3, 4])
print(arr[0])
1
二維陣列想象成一個包含行和列的表格,其中維度 表示行,索引表示列。
arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print('2nd element on 1st row: ', arr[0, 1])
2
三維陣列,訪問第一個陣列的第二個陣列的第三個元素:
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr[0, 1, 2])
6
也和python一樣支援負索引
NumPy 陣列切片
一維的和python一樣
二維的:
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[1, 1:4])
輸出:
[7 8 9]
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[0:2, 2])
輸出:
[3 8]
NumPy 資料型別
i - integer
b - boolean
u - unsigned integer
f - float
c - complex float
m - timedelta
M - datetime
O - object
S - string
U - unicode string
V - fixed chunk of memory for other type ( void )
獲取陣列物件的資料型別:
arr = np.array([1, 2, 3, 4])
arr = np.array(['apple', 'banana', 'cherry'])
print(arr.dtype)
print(arr.dtype)
int32
<U6 (長度不超過6的Unicode字串)
建立資料型別為字串的陣列:
arr = np.array([1, 2, 3, 4], dtype='S')
print(arr)
print(arr.dtype)
[b'1' b'2' b'3' b'4']
|S1 (長度為1的字串)
在現有陣列上轉換資料型別:
arr = np.array([1.1, 2.1, 3.1])
newarr = arr.astype('i')
print(newarr)
print(newarr.dtype)
[1 2 3]
int32
NumPy 陣列副本與檢視
副本擁有資料,對副本所做的任何更改都不會影響原始陣列,並且對原始陣列所做的任何更改都不會影響副本。
檢視不擁有資料,對檢視所做的任何更改都將擁有影響原始陣列,對原始陣列所做的任何更改都將影響檢視。
副本:
arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
檢視:
arr = np.array([1, 2, 3, 4, 5])
x = arr.view()
檢查陣列是否擁有其資料:
arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
y = arr.view()
print(x.base)
print(y.base)
輸出:
None (如果陣列擁有資料,則返回None)
[1 2 3 4 5] (否則,該屬性引用原始物件)
NumPy 陣列形狀
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(arr.shape)
輸出:
(2, 4) (這意味著陣列有 2 個維度, 其中第一個維度有 2 個元素,第二個維度有 4 個元素)
再例:
arr = np.array([1, 2, 3, 4], ndmin=5)
print(arr)
print('shape of array :', arr.shape)
輸出:
[[[[[1 2 3 4]]]]]
shape of array : (1, 1, 1, 1, 4)
# 可以說第 5 個維度有 4 個元素
NumPy 陣列reshape
即:改變陣列的形狀。
透過重塑,我們可以新增或刪除維度或更改每個維度中的元素數量。
從一維到二維重塑:
將以下具有 12 個元素的一維陣列轉換為二維陣列。
最外層的維度將有 4 個陣列,每個陣列有 3 個元素:
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(4, 3)
print(newarr)
輸出:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
從一維到三維重塑:
將以下具有 12 個元素的一維陣列轉換為三維陣列。
最外層維度將有 2 個陣列,每個陣列包含 3 個陣列 有 2 個元素:
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(2, 3, 2)
print(newarr)
輸出:
[[[ 1 2]
[ 3 4]
[ 5 6]]
[[ 7 8]
[ 9 10]
[11 12]]]
返回 Copy 還是 View?
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
print(arr.reshape(2, 4).base)
輸出:
[1 2 3 4 5 6 7 8]
# 因此它是一個檢視。
未知維度
這意味著您不必為其中一個指定確切的數字 Reshape 方法中的尺寸。
傳遞-1作為值,NumPy 將為您計算這個數字。
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(2, 2, -1)
print(newarr)
輸出:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
展平陣列
意味著將多維陣列轉換為一維陣列。
我們可以用它來做到這一點。reshape(-1)
arr = np.array([[1, 2, 3], [4, 5, 6]])
newarr = arr.reshape(-1)
print(newarr)
輸出:
[1 2 3 4 5 6]
NumPy 陣列迭代
迭代一維陣列
arr = np.array([1, 2, 3])
for x in arr:
print(x)
輸出:
1
2
3
迭代二維陣列
arr = np.array([[1, 2, 3], [4, 5, 6]])
for x in arr:
print(x)
輸出:
[1 2 3]
[4 5 6]
# 如果我們迭代一個 n 維陣列,它將一個接一個地經歷 n-1 維。
逐一遍歷:
arr = np.array([[1, 2, 3], [4, 5, 6]])
for x in arr:
for y in x:
print(y)
輸出:
1
2
3
4
5
6
迭代以下 3-D 陣列的元素:
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
for x in arr:
print(x)
輸出:
[[1 2 3]
[4 5 6]]
[[ 7 8 9]
[10 11 12]]
使用 nditer() 迭代陣列
在基本迴圈中,遍歷陣列的每個標量,我們需要使用 n 個for迴圈,這對於具有非常高維數的陣列來說可能很難編寫
arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
for x in np.nditer(arr):
print(x)
輸出:
1
2
3
4
5
6
7
8
使用不同的步長進行迭代
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
for x in np.nditer(arr[:, ::2]):
print(x)
輸出:
1
3
5
7
使用 ndenumerate() 的列舉迭代
列舉意味著逐個提及序列號。
有時我們在迭代時需要元素的相應索引
arr = np.array([1, 2, 3])
for idx, x in np.ndenumerate(arr):
print(idx, x)
輸出:
(0,) 1
(1,) 2
(2,) 3
NumPy 連線陣列
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr = np.concatenate((arr1, arr2))
#沿行堆疊 arr = np.hstack((arr1, arr2))
print(arr)
輸出:
[1 2 3 4 5 6]
沿行連線兩個二維陣列 (axis=1)
arr1 = np.array([[1, 2],
[3, 4]])
arr2 = np.array([[5, 6],
[7, 8]])
arr = np.concatenate((arr1, arr2), axis=1)# 沿行
arr1 = np.concatenate((arr1, arr2), axis=0)# 沿列
print(arr)
print(arr1)
# 維數不變
輸出:
[[1 2 5 6]
[3 4 7 8]]
[[1 2]
[3 4]
[5 6]
[7 8]]
使用堆疊函式聯接陣列
堆疊與串聯相同,唯一的區別是堆疊是沿著新軸完成的。
我們可以沿第二個軸連線兩個一維陣列,這將導致將它們一個放在另一個上
沿列豎著堆疊(axis = 0可以省略)維數+1:
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr = np.stack((arr1, arr2), axis=0)
# axis=0 可以省略
# 等於 arr = np.vstack((arr1, arr2))
print(arr)
輸出:
[[1 2 3]
[4 5 6]]
沿高度(深度)堆疊:
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr = np.stack((arr1, arr2), axis=1)
# arr = np.dstack((arr1, arr2))
print(arr)
輸出:
[[1 4]
[2 5]
[3 6]]
NumPy 拆分陣列
我們用於拆分陣列,我們將要拆分的陣列傳遞給它 以及拆分次數。
arr = np.array([1, 2, 3, 4, 5, 6])
newarr = np.array_split(arr, 3)
print(newarr)
輸出:
[array([1, 2]), array([3, 4]), array([5, 6])]
如果陣列的元素少於所需的元素,它將相應地從末尾進行調整。
arr = np.array([1, 2, 3, 4, 5, 6])
newarr = np.array_split(arr, 4)
print(newarr)
輸出:
[array([1, 2]), array([3, 4]), array([5]), array([6])]
訪問拆分的陣列:
arr = np.array([1, 2, 3, 4, 5, 6])
newarr = np.array_split(arr, 3)
print(newarr[0])
print(newarr[1])
print(newarr[2])
輸出:
[1 2]
[3 4]
[5 6]
拆分二維陣列
將二維陣列拆分為三個二維陣列。
arr = np.array([[1, 2],
[3, 4],
[5, 6],
[7, 8],
[9, 10],
[11, 12]])
newarr = np.array_split(arr, 3)
print(newarr)
輸出:
[array([[1, 2],
[3, 4]]),
array([[5, 6],
[7, 8]]),
array([[ 9, 10],
[11, 12]])]
此外,還可以指定要圍繞哪個軸進行分割。
下面的示例還返回三個二維陣列,但它們沿著深度 (axis=1)
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
[13, 14, 15],
[16, 17, 18]])
newarr = np.array_split(arr, 3, axis=1)
# 沿深度 newarr = np.hsplit(arr, 3)
print(newarr)
輸出:
[array([[ 1],
[ 4],
[ 7],
[10],
[13],
[16]]),
array([[ 2],
[ 5],
[ 8],
[11],
[14],
[17]]),
array([[ 3],
[ 6],
[ 9],
[12],
[15],
[18]])]
NumPy 搜尋陣列
在陣列中搜尋特定值,並返回獲得匹配項的索引。
若要搜尋陣列,請使用以下方法。where()
arr = np.array([1, 2, 3, 4, 5, 4, 4])
x = np.where(arr == 4)
# 查詢值為偶數的索引: x = np.where(arr%2 == 0)
# 查詢值為奇數的索引: x = np.where(arr%2 == 1)
print(x)
輸出:
(array([3, 5, 6], dtype=int64),)
搜尋排序
在陣列中執行二進位制搜尋, 並返回將插入指定值的索引,以保持 搜尋順序。searchsorted()
arr = np.array([6, 7, 8, 9])
x = np.searchsorted(arr, 7)
print(x)
輸出:
1
從右側搜尋:
arr = np.array([6, 7, 8, 9])
x = np.searchsorted(arr, 7, side='right')
print(x)
多個值:
arr = np.array([1, 3, 5, 7])
x = np.searchsorted(arr, [2, 4, 6])
print(x)
輸出:
[1 2 3]
NumPy 排序陣列
arr = np.array([3, 2, 0, 1])
print(np.sort(arr))
輸出:
[0 1 2 3]
對布林陣列進行排序:
arr = np.array([True, False, True])
print(np.sort(arr))
輸出:
[False True True]
對二維陣列進行排序
如果對二維陣列使用 sort() 方法,則兩個陣列都將進行排序:
arr = np.array([[3, 2, 4], [5, 0, 1]])
print(np.sort(arr))
輸出:
[[2 3 4]
[0 1 5]]
NumPy 過濾陣列
從現有陣列中獲取一些元素並建立一個新陣列 其中稱為過濾。
在 NumPy 中,使用布林索引列表篩選陣列。
如果該索引處的值是False,則從篩選陣列中排除該元素。
arr = np.array([41, 42, 43, 44])
x = [True, False, True, False]
newarr = arr[x]
print(newarr)
輸出:
[41 43]
建立篩選器陣列
建立一個僅返回大於 42 的值的篩選器陣列:
arr = np.array([41, 42, 43, 44])
filter_arr = []
for element in arr:
if element > 42: # 根據任務修改這行
filter_arr.append(True)
else:
filter_arr.append(False)
newarr = arr[filter_arr]
print(filter_arr)
print(newarr)
直接從陣列建立過濾器
arr = np.array([41, 42, 43, 44])
filter_arr = arr > 42
newarr = arr[filter_arr]
print(filter_arr)
print(newarr)
輸出:
[False False True True]
[43 44]
NumPy random庫-暫略
NumPy 以下介紹ufuncs
ufuncs 代表“通用函式”,它們是 NumPy 函式, 對ndarray物件進行操作
ufuncs 用於在 NumPy 中實現向量化(將迭代語句轉換為基於向量的操作稱為向量化。),這比迭代元素要快得多。
由於現代 CPU 針對此類操作進行了最佳化,因此速度更快。
沒有 ufunc,我們可以使用 Python 的內建方法:
x = [1, 2, 3, 4]
y = [4, 5, 6, 7]
z = []
for i, j in zip(x, y):
z.append(i + j)
print(z)
輸出:
[5, 7, 9, 11]
使用 ufunc,我們可以使用以下函式:add()
x = [1, 2, 3, 4]
y = [4, 5, 6, 7]
z = np.add(x, y)
print(z)
輸出相同
建立自己的 ufunc
要建立自己的 ufunc,您必須定義一個函式,就像您在 Python 中使用普通函式一樣,然後使用frompyfunc()方法將其新增到您的 NumPy ufunc 庫中。
該方法採用以下引數:frompyfunc()
function- 函式的名稱。
inputs- 輸入引數(陣列)的數量。
outputs- 輸出陣列的數量。
def myadd(x, y):
return x+y
# 輸入2個,輸出1個
myadd = np.frompyfunc(myadd, 2, 1)
print(myadd([1, 2, 3, 4], [5, 6, 7, 8]))
檢查函式的型別以檢查它是否是 ufunc。
print(type(np.add))
輸出:
<class 'numpy.ufunc'>
ufunc 簡單算術
加法:上述已說明(np.add())
減法:
arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([20, 21, 22, 23, 24, 25])
newarr = np.subtract(arr1, arr2)
print(newarr)
輸出:
[-10 -1 8 17 26 35]
乘法:
arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([20, 21, 22, 23, 24, 25])
newarr = np.multiply(arr1, arr2)
print(newarr)
輸出:
[ 200 420 660 920 1200 1500]
除法:
arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 5, 10, 8, 2, 33])
newarr = np.divide(arr1, arr2)
print(newarr)
輸出:
[ 3.33333333 4. 3. 5. 25. 1.81818182]
冪運算:
arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 5, 6, 8, 2, 33])
newarr = np.power(arr1, arr2)
print(newarr)
輸出:
[1000 3200000 729000000 6553600000000 2500 0]
求餘:
arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 7, 9, 8, 2, 33])
newarr = np.mod(arr1, arr2)
# newarr = np.remainder(arr1, arr2)
print(newarr)
輸出:
[1 6 3 0 0 27]
商和餘數:
arr1 = np.array([10, 20, 30, 40, 50, 60])
arr2 = np.array([3, 7, 9, 8, 2, 33])
newarr = np.divmod(arr1, arr2)
print(newarr)
輸出:
(array([ 3, 2, 3, 5, 25, 1]), array([ 1, 6, 3, 0, 0, 27]))
絕對值:
arr = np.array([-1, -2, 1, 2, 3, -4])
newarr = np.absolute(arr)
print(newarr)
ufunc 四捨五入
截斷
刪除小數,並返回最接近零的浮點數。trunc()和fix()
arr = np.trunc([-3.1666, 3.6667])
# arr = np.fix([-3.1666, 3.6667])
print(arr)
輸出:
[-3. 3.]
四捨五入
如果 >=5,則該函式將前面的數字或十進位制遞增 1,否則什麼都不做。
arr = np.around(3.1666, 2)
print(arr)
輸出:
3.17
下取整
將小數四捨五入到最接近的下整數
arr = np.floor([-3.1666, 3.6667])
print(arr)
輸出:
[-4. 3.]
上取整
將小數四捨五入到最接近的大整數
arr = np.ceil([-3.1666, 3.6667])
print(arr)
輸出:
[-3. 4.]
ufunc log()對數函式
NumPy 提供了在基數 2、e 和 10 上執行對數函式。
log2()
使用該函式在基數 2 處執行日誌。log2()
arr = np.arange(1, 10)
print(np.log2(arr))
輸出:
[0. 1. 1.5849625 2. 2.32192809 2.5849625
2.80735492 3. 3.169925 ]
log10()
arr = np.arange(1, 10)
print(np.log10(arr))
輸出:
[0. 0.30103 0.47712125 0.60205999 0.69897 0.77815125
0.84509804 0.90308999 0.95424251]
自然對數
arr = np.arange(1, 10)
print(np.log(arr))
輸出:
[0. 0.69314718 1.09861229 1.38629436 1.60943791 1.79175947
1.94591015 2.07944154 2.19722458]
在任何基底的log
from math import log
import numpy as np
nplog = np.frompyfunc(log, 2, 1)
print(nplog(100, 15))
輸出:
ufunc add()和sum()求和
arr1 = np.array([1, 2, 3])
arr2 = np.array([1, 2, 3])
前面
newarr = np.add(arr1, arr2)
# [2 4 6]
是對應求和
下面 將 arr1 中的值和 arr2 中的值相加:
newarr = np.sum([arr1, arr2])
# 12
newarr = np.sum([arr1, arr2], axis=1)
# [6 6]
累計求和
例如,[1, 2, 3, 4] 的部分和將是 [1, 1+2, 1+2+3, 1+2+3+4] = [1, 3, 6, 10]
newarr = np.cumsum(arr1)
# [1 3 6]
ufunc prod()乘積
arr = np.array([1, 2, 3, 4])
x = np.prod(arr)
print(x)
輸出:
返回:因為 1*2*3*4 = 2424
求兩個陣列元素的乘積:
arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([5, 6, 7, 8])
x = np.prod([arr1, arr2])
# newarr = np.prod([arr1, arr2], axis=1)
print(x)
# print(newarr)
輸出:
返回:因為 1*2*3*4*5*6*7*8 = 40320
# 輸出[24 1680]
累計求積
# 例如,[1, 2, 3, 4] 的偏積為 [1, 1*2, 1*2*3, 1*2*3*4] = [1, 2, 6, 24]
arr = np.array([5, 6, 7, 8])
newarr = np.cumprod(arr)
print(newarr)
輸出:
[5 30 210 1680]
ufunc diff()
離散差值意味著減去兩個連續的元素。
例如,對於 [1, 2, 3, 4],離散差為 [2-1, 3-2, 4-3] = [1, 1, 1]
可以透過給出引數來重複執行此操作。
arr = np.array([10, 15, 25, 5])
newarr = np.diff(arr)
print(newarr)
輸出:
返回:因為 15-10=5、25-15=10 和 5-25=-20[5 10 -20]
計算以下陣列的離散差值兩次:
arr = np.array([10, 15, 25, 5])
newarr = np.diff(arr, n=2)
print(newarr)
輸出:
返回:因為:15-10=5、25-15=10、5-25=-20、10-5=5 和 -20-10=-30[5 -30]
ufunc 查詢 LCM(最小公倍數)
num1 = 4
num2 = 6
x = np.lcm(num1, num2)
print(x)
輸出:
12
在陣列中查詢 LCM
arr = np.array([3, 6, 9])
x = np.lcm.reduce(arr)
print(x)
輸出:
18
求陣列包含從 1 到 10 的所有整數的陣列的所有值的 LCM:
arr = np.arange(1, 11)
x = np.lcm.reduce(arr)
print(x)
輸出:
2520
ufunc GCD(最大公約數)
num1 = 6
num2 = 9
x = np.gcd(num1, num2)
print(x)
在以下陣列中查詢所有數字的 GCD:
arr = np.array([20, 8, 32, 36, 16])
x = np.gcd.reduce(arr)
print(x)
輸出:
4
ufunc 三角函式
x = np.sin(np.pi/2)
print(x)
查詢 arr 中所有值的正弦值:
arr = np.array([np.pi/2, np.pi/3, np.pi/4, np.pi/5])
x = np.sin(arr)
print(x)
輸出:
[1. 0.8660254 0.70710678 0.58778525]
將度數轉換為弧度deg2rad()
注意:弧度值為 pi/180 * degree_values。
arr = np.array([90, 180, 270, 360])
x = np.deg2rad(arr)
print(x)
輸出:
[1.57079633 3.14159265 4.71238898 6.28318531]
弧度到度rad2deg()
arr = np.array([np.pi/2, np.pi, 1.5*np.pi, 2*np.pi])
x = np.rad2deg(arr)
print(x)
輸出:
[ 90. 180. 270. 360.]
尋找角度arcsin()、arccos()、arctan()
x = np.arcsin(1.0)
print(x)
輸出:
1.5707963267948966(pi/2)
斜邊hypot()
base = 3
perp = 4
x = np.hypot(base, perp)
print(x)
輸出:
5
NumPy 雙曲函式暫略
NumPy 集合操作暫略
學習地址W3S