和她糾糾纏纏這麼久了,今天終於下了了斷,花了一個多星期把這個份Numpy上分寶典準備好,你還在等什麼呢?如果你想學數據分析,那我一定推薦你看我這份上分寶典,絕對全網最細,不服就看,帶你學好,學會,學棒!
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我與Numpy之間的那些破事:
學習numpy的理由
比如我們用python的循環來計算下面的平均數計算的話
import time
import numpy as np
start = time.perf_counter()
x = np.random.random(10000000)
x_mean = sum(x) / len(x)
end = time.perf_counter() - start
print('一共耗時爲:{:.4f}s'.format(end))
一共耗時爲:1.3968s
start = time.perf_counter()
y = np.random.random(10000000)
y_mean = np.mean(y)
end = time.perf_counter() -start
print('一共耗時爲:{:.4f}s'.format(end))
一共耗時爲:0.1008s
當我們使用numpy庫的mean方法求平均的時候 時間則大幅減少,這或許是我們學習numpy的理由之一,高效運算
求平均數函數
np.mean()
學習Numpy的方法
numpy的簡單操作和簡單屬性
我們將一維數組稱之爲秩爲 1 的數組。通常,N 維數組的秩爲 N。因此,二維數組稱爲秩爲 2 的數組。數組的另一個重要特性是形狀。數組的形狀是指每個維度的大小。例如,秩爲 2 的數組的形狀對應於數組的行數和列數。你將發現,NumPy ndarray 具有特殊的屬性,使我們能夠非常直觀地獲取關於 ndarray 的信息
%pdb # 魔術方法---調試命令ss
x = np.array([[1, 2, 3, 4, 5],[6, 7, 8, 9, 10]])
print(x)
print(x.dtype) # 類型具有向上轉型成浮點數 同時含有整形和浮點 則轉化爲浮點型
print(type(x)) # 類型: ndarray
print(x.shape) # 根據維度來返回數組的形狀 這裏 2行 五列
print(x.size) # 返回數組的大小
print(np.mean(x)) # 求數組的平均數
Incorrect argument. Use on/1, off/0, or nothing for a toggle.
[[ 1 2 3 4 5]
[ 6 7 8 9 10]]
int32
<class 'numpy.ndarray'>
(2, 5)
10
5.5
將python類型轉換爲ndarray類型 進行運算
print('np.array()這個是最基礎的創建一個數組函數')
np.array()這個是最基礎的創建一個數組函數
列表轉換
a_list = [11, 12, 13, 14, 15]
ax = np.array(a_list)
print(f'a= {a_list}')
print('a的平均數爲 =',np.mean(ax))
a= [11, 12, 13, 14, 15]
a的平均數爲 = 13.0
字符串轉換
y = np.array(['hello', 'world','are you ok'])
print(f'y = {y}')
print('形狀元組 = ', y.shape)
print(y.dtype) # 10個unicode字符
y = ['hello' 'world' 'are you ok']
形狀元組 = (3,)
<U10
請務必注意,Python 列表和 ndarray 之間的最大區別是:與 Python 列表不同的是,ndarray 的所有元素都必須類型相同。因此,雖然我們可以同時使用整數和字符串創建 Python 列表,但是無法在 ndarray 中同時使用這兩種類型。如果向 np.array() 函數提供同時具有整數和字符串的 Python 列表,NumPy 會將所有元素解析爲字符串
z = np.array([123, 'hello'])
print(z.dtype) # 這個時候就解析成了字符串
<U11
數組的保存和讀取
x = np.arange(10).reshape((2, 5))
np.save('my_array', x) # 保存到文件夾
x = np.load('my_array.npy') # 數組的讀取方式
print('x= \n', x)
x=
[[0 1 2 3 4]
[5 6 7 8 9]]
使用numpy中內置函數生成數組
創建一個全0的數組
必要的時候我們也可以指定數組的類型,在這裏我們改變y的類型,我們也可以使用reshape改變形狀,我們來試試!
x = np.zeros((4,4))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
y = np.zeros((5,5), dtype=int)
print('y=\n{} shape = {} type = {}'.format(y, y.shape, y.dtype))
x = x.reshape((2,8)) # 在這裏我們把x改成 2 * 8 的數組 但是一定要確保size一樣大小,不然會報錯
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]] shape = (4, 4) type = float64
y=
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]] shape = (5, 5) type = int32
x=
[[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]] shape = (2, 8) type = float64
創建一個全爲1的數組
x = np.ones((4, 4))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]] shape = (4, 4) type = float64
創建一個指定形狀的數組
使用 np.full(shape, constant value) 函數有兩個參數。第一個參數是你要創建的 ndarray 的形狀,第二個參數是你要向數組中填充的常數值,那我們來試試
x = np.full((4, 4), 5)
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[5 5 5 5]
[5 5 5 5]
[5 5 5 5]
[5 5 5 5]] shape = (4, 4) type = int32
如果你很細心的話,你會發現線性代數中的基本數組是單位矩陣。單位矩陣是主對角線上全是 1,其他位置全是 0 的方形矩陣。而函數 np.eye(N) 會創建一個對應於單位矩陣的方形 N x N ndarray。因爲所有單位矩陣都是方形,因此,np.eye() 函數僅接受一個整數作爲參數。我們來看一個示例:
創建單位數組
x = np.eye(4, dtype = int) # 接受一個n值 函數會自動創建一個n * n 的單位矩陣 你也可以更改數組的類型
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]] shape = (4, 4) type = int32
創建給定值對角矩陣
我們使用np.diag() 創建一個給定值的對角矩陣
x = np.diag([10, 20, 30, 40])
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[10 0 0 0]
[ 0 20 0 0]
[ 0 0 30 0]
[ 0 0 0 40]] shape = (4, 4) type = int32
NumPy 還允許你創建在給定區間內值均勻分佈的 ndarray。 np.arange(start,stop,step)左閉右開
NumPy 的np.arange() 函數非常強大,可以傳入一個參數、兩個參數或三個參數。下面將介紹每種情況,以及如何創建不同種類的 ndarray
創建整數數組
x = np.arange(10) # 當傳入一個值的時候 表示 0-9 默認步長爲1 的一維矩陣
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
y = np.arange(2,10) # 當傳入二個值的時候 2-9
print('y=\n{} shape = {} type = {}'.format(y, y.shape, y.dtype))
z = np.arange(2,10,2) # 當傳入三個值的時候 2-9 步長爲2
print('z=\n{} shape = {} type = {}'.format(z, z.shape, z.dtype))
x=
[0 1 2 3 4 5 6 7 8 9] shape = (10,) type = int32
y=
[2 3 4 5 6 7 8 9] shape = (8,) type = int32
z=
[2 4 6 8] shape = (4,) type = int32
但是這種情況是對於整數來說,雖然這個方法可以創建小數的數組,但是我們不建議這樣做,精度很低,這裏提供了一個新的函數np.linspace(start, stop, N)左閉右閉 N爲表示等差分爲多少份,我們來試試!
創建小數數組
x = np.linspace(1,10,5)
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[ 1. 3.25 5.5 7.75 10. ] shape = (5,) type = float64
ps:加入關鍵詞 endpoint = False 可以讓這個方法不適用結尾的數
創建隨機數組
我們也可以創建隨機的數組np.random.randint([statr, stop), shape)
擴展:np.random.permutation(N) 函數會創建一個從 0 到 N - 1的隨機排列的整數集
x = np.random.randint(1,5,(5,5))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[4 3 2 4 1]
[1 2 1 2 2]
[4 4 1 3 4]
[4 3 2 2 2]
[3 3 2 4 1]] shape = (5, 5) type = int32
這裏我們對應一下random模塊中的randint 區別在於 random模塊中的randint的區間範圍是二邊閉口
import random
x = [random.randint(1,3) for i in range(50)]
print(x)
[2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 2, 1, 2, 3, 2, 3, 3, 3, 2, 3, 1, 2, 1, 3, 2, 2, 2, 1, 2, 3, 2, 2, 2, 1, 3, 1, 2, 2, 3, 3, 2, 1, 3, 3, 3, 2, 2, 2, 3]
創建特定數組
在某些情況下,你可能需要創建由滿足特定統計學特性的隨機數字組成的 ndarray。例如,你可能希望 ndarray 中的隨機數字平均值爲 0。NumPy 使你能夠創建從各種概率分佈中抽樣的數字組成的隨機 ndarray。例如,函數 np.random.normal(mean, standard deviation, size=shape) 會創建一個具有給定形狀的 ndarray,其中包含從正態高斯分佈(具有給定均值和標準差)中抽樣的隨機數字。我們來創建一個 1,000 x 1,000 ndarray,其中包含從正態分佈(均值爲 0,標準差爲 0.1)中隨機抽樣的浮點數
x = np.random.normal(0, 0.1, size = (1000,1000))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
print(f'平均數 {np.mean(x)}') # 平均數無線接近爲0
print(f'max {np.max(x)}')
print(f'min {np.min(x)}')
x=
[[ 0.17472034 0.16466766 0.20174347 ... 0.0553319 -0.01653249
0.03948098]
[ 0.06888259 0.0134556 -0.01425262 ... 0.06732574 -0.05307537
0.03314621]
[-0.02105612 -0.12779988 0.18961712 ... -0.09320825 -0.0666076
-0.05079914]
...
[ 0.06068892 0.07034235 -0.01217326 ... -0.11759619 -0.00506101
-0.06323254]
[ 0.02748854 -0.012596 -0.07722798 ... -0.06668634 0.11173246
-0.16214736]
[ 0.08337674 0.13369851 -0.14506456 ... 0.16990955 0.09465047
0.04350329]] shape = (1000, 1000) type = float64
平均數 -7.668087217691369e-05
max 0.5025681985823912
min -0.5569429250768674
數組的訪問,刪除,修改,增加, 插入和疊片
元素訪問,賦值修改
若是一維數組,訪問的方式和字符串一樣,不做介紹,若是二維數組,訪問存在二種方式,例如我下方的例子,可以x[0, 0]或者x[0][0] 看個人喜愛
ps: 索引值均從0開始計算
x = np.arange(1,11).reshape((2, 5))
print(x)
print(f'x[0, 0] = {x[0,0]}')
print(f'x[1, 1] = {x[1][1]}')
print(f'x[1, 3] = {x[1][3]}')
x[1,3] = 99 # 直接賦值修改
print(f'x[1, 3] = {x[1][3]}\n')
print(x)
[[ 1 2 3 4 5]
[ 6 7 8 9 10]]
x[0, 0] = 1
x[1, 1] = 7
x[1, 3] = 9
x[1, 3] = 99
[[ 1 2 3 4 5]
[ 6 7 8 99 10]]
元素刪除
np.delete(ndarray, elements, axis) 函數刪除元素。此函數會沿着指定的軸從給定 ndarray 中刪除給定的元素列表。對於秩爲 1 的 ndarray,不需要使用關鍵字 axis。對於秩爲 2 的 ndarray,axis = 0 表示選擇行,axis = 1 表示選擇列。我們來看一些示例
x = np.arange(0,10) # 對於一維數組
print(f'before \n{x}')
x = np.delete(x, [0,9])
print(f'after \t\t刪除第0個和第9個\n {x}')
print('-'*40)
y = np.arange(0,15).reshape((3,5)) # 對於二維數組
print(f'before \n {y}')
y_1 = np.delete(y, 0, axis = 0)
print(f'after1 \t\t刪除第0行 \n {y_1}')
y_2 = np.delete(y, [0,1], axis = 0)
print(f'after2 \t\t刪除第0和第1行\n {y_2}')
print('-'*40)
y_3 = np.delete(y, 0, axis = 1)
print(f'after3 \t\t 刪除第一列\n {y_3}')
y_4 = np.delete(y, [0,1], axis =1)
print(f'after4 \t\t 刪除第一列和第二列\n {y_4}')
before
[0 1 2 3 4 5 6 7 8 9]
after 刪除第0個和第9個
[1 2 3 4 5 6 7 8]
----------------------------------------
before
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
after1 刪除第0行
[[ 5 6 7 8 9]
[10 11 12 13 14]]
after2 刪除第0和第1行
[[10 11 12 13 14]]
----------------------------------------
after3 刪除第一列
[[ 1 2 3 4]
[ 6 7 8 9]
[11 12 13 14]]
after4 刪除第一列和第二列
[[ 2 3 4]
[ 7 8 9]
[12 13 14]]
元素增加
使用 np.append(ndarray, elements, axis) 函數向 ndarray 中附加值。該函數會將給定的元素列表沿着指定的軸附加到 ndarray 中
一維數組的增加就是往後疊,二維數組的增加還需要添加axis的值,和刪除同理,0爲行1爲列,增加要考慮行和列是否對齊,簡單來說,形狀對齊,下面我們來試試一些例子
print('對於一維數組'.center(40,'-'))
x = np.arange(10)
print(f'before \t {x}')
x = np.append(x , 10)
print(f'after \t {x}')
print('對於二維數組'.center(40,'-'))
y = np.arange(0,15).reshape((3,5))
print(f'before=\n{y}')
y_1 = np.append(y, [[0, 1, 2, 4, 5]], axis = 0)
print(f'after=增加在最後一行\n{y_1}')
y_2 = np.append(y, [[0],[0],[0]], axis = 1)
print(f'after=增加在最後一列\n{y_2}')
-----------------對於一維數組-----------------
before [0 1 2 3 4 5 6 7 8 9]
after [ 0 1 2 3 4 5 6 7 8 9 10]
-----------------對於二維數組-----------------
before=
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
after=增加在最後一行
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[ 0 1 2 4 5]]
after=增加在最後一列
[[ 0 1 2 3 4 0]
[ 5 6 7 8 9 0]
[10 11 12 13 14 0]]
元素插入
使用 np.insert(ndarray, index, elements, axis) 函數向 ndarray 中插入值。此函數會將給定的元素列表沿着指定的軸插入到 ndarray 中,並放在給定的索引前面。我們來看一些例子把
print('對於一維數組'.center(40, '-'))
x = np.arange(10)
print(f'before=\n{x}')
x = np.insert(x, 1, [10])
print(f'after=我們在下標爲1的位置插入10\n{x}')
print('對於二維數組'.center(40, '-'))
y = np.arange(15).reshape((3, 5))
print(f'before=\n{y}')
y_1 = np.insert(y, 1,[[5, 5, 5, 5, 5]], axis =0)
print(f'after_1=我們在第一行的位置插入五個五\n{y_1}')
y_2 = np.insert(y, 1, [[6]], axis = 1)
print(f'after_2=我們在第一列的位置插入三個6\n{y_2}')
-----------------對於一維數組-----------------
before=
[0 1 2 3 4 5 6 7 8 9]
after=我們在下標爲1的位置插入10
[ 0 10 1 2 3 4 5 6 7 8 9]
-----------------對於二維數組-----------------
before=
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
after_1=我們在第一行的位置插入五個五
[[ 0 1 2 3 4]
[ 5 5 5 5 5]
[ 5 6 7 8 9]
[10 11 12 13 14]]
after_2=我們在第一列的位置插入三個6
[[ 0 6 1 2 3 4]
[ 5 6 6 7 8 9]
[10 6 11 12 13 14]]
疊片操作
可以使用 np.vstack() 函數進行垂直堆疊,或使用 np.hstack() 函數進行水平堆疊。請務必注意,爲了堆疊 ndarray,ndarray 的形狀必須相符。我們來看一些例子
x = np.arange(4).reshape((2,2))
print(f'x=\n{x}')
y = np.array([4, 5])
print(f'y=\n{y}')
print('水平疊片'.center(40, '-'))
x_h = np.hstack((x, y.reshape(2, 1)))
print(f'y水平疊在x的後面\n{x_h}')
print('垂直疊片'.center(40, '-'))
x_v = np.vstack((x, y))
print(f'y垂直疊在x的下面\n{x_v}')
x=
[[0 1]
[2 3]]
y=
[4 5]
------------------水平疊片------------------
y水平疊在x的後面
[[0 1 4]
[2 3 5]]
------------------垂直疊片------------------
y垂直疊在x的下面
[[0 1]
[2 3]
[4 5]]
元素等切
np.hsplit(ndarray, n) # 將數組等分和豎着等切
np.vsplit(ndayyay, n) # 將數組等分和橫着等切
import numpy as np
x = np.arange(6).reshape((2,3))
print('x=\n',x)
x_1 = np.hsplit(x,3)
print(f'將x等分爲三份,這裏取第一段=\n',x_1[0])
x_2 =np.hsplit(x,(0,1))
print(f'在第0個位置前和第1個位置前豎着切=\n',x_2)
print('np.vsplit() 用法一樣')
x=
[[0 1 2]
[3 4 5]]
將x等分爲三份,這裏取第一段=
[[0]
[3]]
在第0個位置前和第1個位置前豎着切=
[array([], shape=(2, 0), dtype=int32), array([[0],
[3]]), array([[1, 2],
[4, 5]])]
np.vsplit() 用法一樣
數組的切片操作
一維數組的切片
import numpy as np
print('一維數組的切片'.center(40, '-'))
x = np.arange(10)
print(f'before \n{x}')
print(f'after 切前三個元素 \n{x[:3]}')
----------------一維數組的切片-----------------
before
[0 1 2 3 4 5 6 7 8 9]
after 切前三個元素
[0 1 2]
二維數組的切片
二維數組的切片x[行:列] :切片的順序都是按照先行 後列
print('二維數組的切片'.center(40, '-'))
x = np.arange(20).reshape((4, 5))
print(f'before \n{x}')
x_1 = x[:3,:3]
print(f'after 切前三行前三列的交叉元素 \n{x_1}')
x_2 = x[1:3,1:3]
print(f'after 切第二行第三行 和第二列第三列的交叉元素 \n{x_2}')
print('行賦空操作'.center(40,'-'))
x_3 = x[ : ,2]
x_4 = x[ : ,2:3]
print(f'after\t行賦空的話,則代表行全選,這裏取第三列\n{x_3}\tshape={x_3.shape} \t 這就變成了一維數組')
print(f'after\t這種手法,切列的操作,和上面不一樣\n{x_4}\t\tshape={x_4.shape}\t 這樣就變成了二維數組')
print('列賦空操作'.center(40, '-'))
x_5 = x[1, : ]
print(f'after 列賦空,則取第二行\n{x_5}')
----------------二維數組的切片-----------------
before
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
after 切前三行前三列的交叉元素
[[ 0 1 2]
[ 5 6 7]
[10 11 12]]
after 切第二行第三行 和第二列第三列的交叉元素
[[ 6 7]
[11 12]]
-----------------行賦空操作------------------
after 行賦空的話,則代表行全選,這裏取第三列
[ 2 7 12 17] shape=(4,) 這就變成了一維數組
after 這種手法,切列的操作,和上面不一樣
[[ 2]
[ 7]
[12]
[17]] shape=(4, 1) 這樣就變成了二維數組
-----------------列賦空操作------------------
after 列賦空,則取第二行
[5 6 7 8 9]
切片的修改操作
x = np.arange(20).reshape((4,5))
print(f'before\n{x}')
x_1 = x[:2, :2]
print(f'after 隨便切點數據 \n {x_1}')
print('我們嘗試對切好數據進行修改')
x_1[0,0] = 55
print(f'修改x_1[0,0] = 55 \nafter\n{x_1}')
print(f'此時x\n{x}')
before
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
after 隨便切點數據
[[0 1]
[5 6]]
我們嘗試對切好數據進行修改
修改x_1[0,0] = 55
after
[[55 1]
[ 5 6]]
此時x
[[55 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
這裏我們就會發現對於x_1的修改操作,原數組x居然也會改變,這與我們之前理解的字符串切片貌似不一樣啊,在這裏我必須得強調,他們二個都是同一個
ndarray屬性的不同名稱而已,如果用c來講,他們的地址是一樣的,只不過指向了不同的地方,他只是創建了原數組的一個視圖,所以我們修改後者,前者也會發生變化,那我們就不能修改了? 別急,python還提供了一個新的函數,**np.copy(ndarray)**這個函數會創建一個新的副本,那我們就可以修改了
下面給出例子
創建副本數組
x = np.arange(20).reshape((4,5))
x_1 = x[:3, :3].copy()
x_2 = np.copy(x[:3, :3])
print('代碼上面給出了二種copy的方法')
print(f'x=\n{x}')
print(f'after隨意切點=\n{x_1}')
x_1[0,0] = 555
print(f'after修改之後的x_1 =\n{x_1}')
print(f'afrer修改之後的x=\n{x}')
print('這樣操作原數組就不會發生變化')
代碼上面給出了二種copy的方法
x=
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
after隨意切點=
[[ 0 1 2]
[ 5 6 7]
[10 11 12]]
after修改之後的x_1 =
[[555 1 2]
[ 5 6 7]
[ 10 11 12]]
afrer修改之後的x=
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
這樣操作原數組就不會發生變化
數組與數組之間相互切片
x = np.arange(20).reshape((4,5))
y = np.array([1,3])
print('x=\n',x)
print('y=',y)
print()
print('在x數組中使用y進行切片'.center(40, '-'))
print(f'after 行賦空切,這裏切第2列和第四列=\n{x[ : ,y]}')
print(f'after 列賦空切, 這裏切第2行和第四行=\n{x[y, : ]}')
x=
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
y= [1 3]
--------------在x數組中使用y進行切片--------------
after 行賦空切,這裏切第2列和第四列=
[[ 1 3]
[ 6 8]
[11 13]
[16 18]]
after 列賦空切, 這裏切第2行和第四行=
[[ 5 6 7 8 9]
[15 16 17 18 19]]
對角線切片
NumPy 還提供了從 ndarray 中選擇特定元素的內置函數。例如,np.diag(ndarray, k=N) 函數會以 N 定義的對角線提取元素。默認情況下,k=0,表示主對角線。k > 0 的值用於選擇在主對角線之上的對角線中的元素,k < 0 的值用於選擇在主對角線之下的對角線中的元素。我們來看一個示例
x = np.arange(20).reshape((4,5))
print('x=\n',x)
print()
x_1 = np.diag(x)
print(f'切x的主對角線\t{x_1}\n')
x_2 = np.diag(x, k=1)
print(f'切x的主對角線上面的一對\t{x_2}\n')
x_3 = np.diag(x ,k=-1)
print(f'切x的主對角線下面的一對\t{x_3}\n')
x=
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
切x的主對角線 [ 0 6 12 18]
切x的主對角線上面的一對 [ 1 7 13 19]
切x的主對角線下面的一對 [ 5 11 17]
切唯一元素
可以使用 np.unique() 函數查找 ndarray 中的唯一元素。np.unique(ndarray) 函數會返回給定 ndarray 中的 唯一元素(去重後的元素)看一個例子
x = np.random.randint(0,3,(4,5)) # 這裏使用random隨機數組
print('x=\n',x)
print(f'x中的唯一元素爲: {np.unique(x)}')
x=
[[0 2 0 1 2]
[0 0 2 0 2]
[1 0 2 2 2]
[0 2 1 2 2]]
x中的唯一元素爲: [0 1 2]
數組的布爾型索引,集合運算和排序
可能有人要問,我們之前不是學過數組的訪問和切片,那爲啥還要學這個,我們想一想,前者我們是有確定值或者確定位置,那如果我們沒有確定的消息
呢,一切都是未知的,我們需要按照一個範圍來獲得我們需要的元素,那麼布爾型索引這個就可以完成我們的任務,下面看一個例子
數組的布爾型索引
x = np.arange(25).reshape((5,5))
print('x=\n',x)
print(f'查找大於14的數 = \n {x[x>14]}')
print(f'查找小於等於5的數 = \n {x[x<=5]}')
print(f'查找大於10小於20的數 =\n {x[(x>10) & (x<20)]}')
x=
[[ 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]]
查找大於14的數 =
[15 16 17 18 19 20 21 22 23 24]
查找小於等於5的數 =
[0 1 2 3 4 5]
查找大於10小於20的數 =
[11 12 13 14 15 16 17 18 19]
ps:索引裏面的判斷式 不僅僅是我給出的這麼的簡單判斷,還可以擴展很多表達式,可以自行探索探索
數組的集合運算
np.intersect1d() 交集
np.setdiff1d() 差集
np.union1d() 全集
注意這個1d 是數字1 不是字母l 這個我破梗我抗了這麼多下終於發現
x = np.random.randint(1, 8, (3,3))
print('x=\n',x)
y = np.random.randint(2, 10,(3,3))
print('y=\n',y)
print(f'x和y的交集元素=\n {np.intersect1d(x,y)}')
print(f'x和y的差集元素=\n {np.setdiff1d(x,y)}')
print(f'x和y的全集元素=\n {np.union1d(x,y)}')
x=
[[5 1 7]
[7 6 1]
[1 2 2]]
y=
[[2 3 7]
[7 3 7]
[5 6 8]]
x和y的交集元素=
[2 5 6 7]
x和y的差集元素=
[1]
x和y的全集元素=
[1 2 3 5 6 7 8]
數組的排序
x = np.random.randint(1,10,(10,))
print('x=\n',x)
print('第一種排序方式 x = \n',np.sort(x))
print('after x = \n', x)
print('第二種排序方式 x = ')
x.sort()
print(x)
print('after x =\n',x)
x=
[4 9 3 8 8 8 4 7 5 1]
第一種排序方式 x =
[1 3 4 4 5 7 8 8 8 9]
after x =
[4 9 3 8 8 8 4 7 5 1]
第二種排序方式 x =
[1 3 4 4 5 7 8 8 8 9]
after x =
[1 3 4 4 5 7 8 8 8 9]
ps:當使用sort當作函數來使用,我們不會改變原數組x,當我們使用sort當作方式來使用,我們會改變原數組x,而且sort()中也可以加入axis參數,同樣0爲行1爲列去判斷排序的行還是列
x = np.random.randint(1,16,(5,3))
print('x=\n',x)
print()
print(f'對行排序 =\n {np.sort(x, axis = 0)}\n')
print(f'對列排序 = \n {np.sort(x , axis = 1)}\n')
print('行和列的選擇取決於axis的值,仍然是0爲行,1爲列')
x=
[[14 5 11]
[ 9 15 15]
[ 3 12 8]
[ 5 5 4]
[ 4 10 7]]
對行排序 =
[[ 3 5 4]
[ 4 5 7]
[ 5 10 8]
[ 9 12 11]
[14 15 15]]
對列排序 =
[[ 5 11 14]
[ 9 15 15]
[ 3 8 12]
[ 4 5 5]
[ 4 7 10]]
行和列的選擇取決於axis的值,仍然是0爲行,1爲列
數組的排序加強版
我們也可以對排序後的值去重操作,在上面我們使用了切唯一值函數np.unique() 這裏也可以使用
x = np.array([1,2,1,4,2,6,3,8])
print('x=',x)
print(f'排序並去重 = {np.sort(np.unique(x))}')
x= [1 2 1 4 2 6 3 8]
排序並去重 = [1 2 3 4 6 8]
數組的算數運算和廣播操作
算數運算
相加 x+y 或者np.add()
相減 x-y 或者np.subtract()
相乘 x*y 或者np.multiply(x,y)
相除 x/y 或者np.divide(x,y)
print('一維數組的操作'.center(40,'-'))
x = np.arange(5)
y = np.arange(5,10)
print('x=',x)
print('y=',y)
print(f'相加使用x+y = {x+y}')
print(f'相加使用add = {np.add(x,y)}')
----------------一維數組的操作-----------------
x= [0 1 2 3 4]
y= [5 6 7 8 9]
相加使用x+y = [ 5 7 9 11 13]
相加使用add = [ 5 7 9 11 13]
print('二維數組的操作'.center(40,'-'))
x = np.arange(10).reshape((2,5))
y = np.arange(10,20).reshape((2,5))
print('x=\n',x)
print('y=\n',y)
print(f'相乘使用x*y = {x * y}')
print(f'相乘使用multiply = {np.multiply(x,y)}')
----------------二維數組的操作-----------------
x=
[[0 1 2 3 4]
[5 6 7 8 9]]
y=
[[10 11 12 13 14]
[15 16 17 18 19]]
相乘使用x*y = [[ 0 11 24 39 56]
[ 75 96 119 144 171]]
相乘使用multiply = [[ 0 11 24 39 56]
[ 75 96 119 144 171]]
數學函數
! 這裏重要提一個函數 np.mean()求平均數 裏面參數一個對象ndarray還有一個axis這二個很重要
! 當axis = 0 的時候,壓縮行,求每列的均值
! 當axis = 1 的時候,壓縮列,求每行的均值
怎麼理解呢,你就把這個數組當成一個千層餅一樣,行壓縮就是垂直把這個千層餅壓扁,從上面看數量上不就和列個數相同。
列壓縮,就水平的把千層餅壓扁,從左右看數量上不就等於行的個數了
x = np.arange(5)
print('x=',x)
print(f'冪運算exp = {np.exp(x)}')
print(f'開根號運算 sqrt = {np.sqrt(x)}')
print(f'平方運算 power = {np.power(x,2)}')
print(f'平均數 mean = {np.mean(x)}')
print(f'最大數 max = {np.max(x)}')
print(f'最小數 min = {np.min(x)}')
print(f'總數sum = {np.sum(x)}')
print(f'標準差 std = {np.std(x)}')
print(f'中位數 median = {np.median(x)}')
print('對於二維數組來說,只要在裏面增加參數axis 同樣行爲0列爲1')
x= [0 1 2 3 4]
冪運算exp = [ 1. 2.71828183 7.3890561 20.08553692 54.59815003]
開根號運算 sqrt = [0. 1. 1.41421356 1.73205081 2. ]
平方運算 power = [ 0 1 4 9 16]
平均數 mean = 2.0
最大數 max = 4
最小數 min = 0
總數sum = 10
標準差 std = 1.4142135623730951
中位數 median = 2.0
對於二維數組來說,只要在裏面增加參數axis 同樣行爲0列爲1
廣播操作
x = np.arange(10).reshape((2,5))
print('x=\n',x)
print()
print(f'x+2 =\n {x+2}')
print()
print(f'x*2 =\n{x*2}')
x=
[[0 1 2 3 4]
[5 6 7 8 9]]
x+2 =
[[ 2 3 4 5 6]
[ 7 8 9 10 11]]
x*2 =
[[ 0 2 4 6 8]
[10 12 14 16 18]]
在這裏numpy將數字2進行了廣播操作,意思就是把他的形狀和要進行操作的數組進行了同化,這樣就能簡單的進行數組的變化,下面拿出特殊的例子來看看
x = np.arange(3)
y = np.arange(9).reshape((3,3))
z = np.arange(9,12).reshape((3,1))
print('x=',x)
print()
print('y=\n',y)
print()
print('z=\n',z)
print()
print(f'x+y =\n {x+y}')
print()
print(f'y+z =\n {y+z}')
x= [0 1 2]
y=
[[0 1 2]
[3 4 5]
[6 7 8]]
z=
[[ 9]
[10]
[11]]
x+y =
[[ 0 2 4]
[ 3 5 7]
[ 6 8 10]]
y+z =
[[ 9 10 11]
[13 14 15]
[17 18 19]]
這裏雖然二個數組的形狀不一樣,但是我們也可以進行操作,也是運用了廣播操作,對於x+y numpy把x同化y,對於y+z numpy把z同化y,這樣就可以進行操作,總之就是把較小數組同化成爲較大數組。
後記:我認爲學習是一個持久的事情,學習一個函數庫也是一樣,不可能我們一下子能記住這麼多函數,看了這麼多python官網文獻,我也只是記得經常用的,但是沒有什麼能阻攔我們學習的心,兄弟們,幹他就完事了,趁現在還年輕,能學,那就不要放棄,若干年後,你會感謝今天的付出,你也會感謝你看過的這篇文章,我也會感謝你爲我點的贊和關注,這是我堅持下去的一個動力,非常感謝。
正所謂 長風破浪會有時,直掛直掛雲帆濟滄海!