不看你一定後悔,基於 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官網文獻,我也只是記得經常用的,但是沒有什麼能阻攔我們學習的心,兄弟們,幹他就完事了,趁現在還年輕,能學,那就不要放棄,若干年後,你會感謝今天的付出,你也會感謝你看過的這篇文章,我也會感謝你爲我點的贊和關注,這是我堅持下去的一個動力,非常感謝。
正所謂 長風破浪會有時,直掛直掛雲帆濟滄海!

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