Numpy的入門級使用

Numpy的使用

一、Array數組簡介

# 導包,簡化名稱
import numpy as np
# 獲取版本
np.__version__
'1.18.1'
# 使用np的array
nparr = np.array([i for i in range(10)])
nparr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 查看某個元素
nparr[4]
4
# 修改某個元素值
nparr[4]=12
nparr[4]
12
# np的array默認是64位int型,即使用浮點數依然是自動轉爲int
# 如果在初始化的時候使用了浮點數,則會轉爲浮點數
nparr2 = np.array([1, 2, 3.0])
nparr2.dtype
dtype('float64')

二、其他創建np的數組方法

#創建10個值爲0的數組/矩陣
np.zeros(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
#默認浮點數
np.zeros(10).dtype
dtype('float64')
# 創建三行五列的矩陣
np.ones(shape=(3,5), dtype=int)
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]])
# 創建相同指定元素的矩陣,可以省略shape和fill_value
np.full(shape=(3,5), fill_value=10.0)
array([[10., 10., 10., 10., 10.],
       [10., 10., 10., 10., 10.],
       [10., 10., 10., 10., 10.]])

arange循環

# for(i=0;i<20;i+2)
np.arange(0, 20, 2)
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
np.arange(2, 17).reshape(3,5)
array([[ 2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16]])

linspace 在指定全閉空間截取等長的指定長度

np.linspace(0, 20, 11)
array([ 0.,  2.,  4.,  6.,  8., 10., 12., 14., 16., 18., 20.])

隨機數random

# 在4-8範圍內生成3行5列的隨機矩陣
np.random.randint(4, 8, size=(3,5))
array([[7, 4, 5, 5, 4],
       [5, 4, 7, 6, 7],
       [5, 5, 7, 7, 7]])
# 指定隨機種子,這樣可以保證兩次生成的隨機數一樣
np.random.seed(100)
np.random.randint(4, 8, size=(3,5))
array([[4, 4, 7, 7, 7],
       [7, 4, 6, 6, 4],
       [6, 5, 6, 6, 6]])
np.random.seed(100)
np.random.randint(4, 8, size=(3,5))
array([[4, 4, 7, 7, 7],
       [7, 4, 6, 6, 4],
       [6, 5, 6, 6, 6]])
# 生成隨機的浮點數,是0-1的均勻分佈
np.random.random((4, 8))
array([[0.4527399 , 0.87014264, 0.06368104, 0.62431189, 0.52334774,
        0.56229626, 0.00581719, 0.30742321],
       [0.95018431, 0.12665424, 0.07898787, 0.31135313, 0.63238359,
        0.69935892, 0.64196495, 0.92002378],
       [0.29887635, 0.56874553, 0.17862432, 0.5325737 , 0.64669147,
        0.14206538, 0.58138896, 0.47918994],
       [0.38641911, 0.44046495, 0.40475733, 0.44225404, 0.03012328,
        0.77600531, 0.55095838, 0.3810734 ]])
# 生成符合正態分佈的浮點數,比如均值爲4,方差爲10的浮點數
# 因爲生活中很多事物都是符合正態分佈的,不如身高,所以有時候需要這樣的數據採樣
np.random.normal(4, 10, size=(3, 5))
array([[ 9.92575746,  4.37958129,  7.71967572,  7.59753947,  2.59603535],
       [-0.43738512,  9.68770162,  9.38488768, 17.15574179, 18.78978297],
       [ 6.21426255, -7.17894159,  2.1500007 , -0.31187446,  5.42536252]])
#查詢具體函數的文檔說明 可以使用【help(np.random.normal)】將文檔插入notebook
np.random.normal?

三、數組的基本屬性

# 定義一維數組x
x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 定義二維數組X
X = np.arange(15).reshape(3,5)
X
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
# 查詢是維度
x.ndim
1
X.ndim
2
# 查詢構建情況,即元組情況
x.shape
(10,)
X.shape
(4, 3)
# 獲取第一個維度(行維度)數據,即有多少行
X.shape[0]
4
# 元素個數
x.size
10
X.size
12

數據訪問

# -1表示最後一個元素
x[-1]
9
# 二維數組訪問方式,比如訪問第2行第2列元素,注意下標從0開始
X[2,2]
12
# [:5]從頭到第5個元素,[5:]從第五個元素到結尾
# [::2]以2爲步長訪問所有元素
x[::2]
array([0, 2, 4, 6, 8])
# [::-1]倒序訪問
x[::-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
# 二維數組訪問前兩行前兩列,進行切片
X[:2, :3]
array([[0, 1, 2],
       [5, 6, 7]])
# 抽出所有的行,選取第三列數據轉爲一維向量
X[:, 2]
array([ 2,  7, 12])
# 抽出所有的列,選取第2行數據轉爲一維,就是選取第二行數據
X[1, :]
array([5, 6, 7, 8, 9])
# 獲取子矩陣
subX = X[:2, :3]
subX
array([[0, 1, 2],
       [5, 6, 7]])
# 如果修改子矩陣的元素,則原矩陣也會變;反之亦然
# 也就是說子矩陣並未完全脫離原矩陣
subX[0, 2] = 10
subX
array([[ 0,  1, 10],
       [ 5,  6,  7]])
X
array([[ 0,  1, 10,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
# 所以,我們需要創建一個完全脫離原矩陣的矩陣
subX = X[:2, :3].copy()
subX
array([[ 0,  1, 10],
       [ 5,  6,  7]])
subX[0,0]=100
subX
array([[100,   1,  10],
       [  5,   6,   7]])
X
array([[ 0,  1, 10,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

Reshape改變維度

x1 = np.arange(10)
x1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x1.ndim
1
x1.shape
(10,)
# 轉爲二維,但是沒有改變x1本身維度
A = x1.reshape(2, 5)
x1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
A
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
# 讓計算機自己計算另一個維度的元素個數
# 比如指定10行,注意中英文標點符號切換
A.reshape(10,-1)
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
A.reshape(2,-1)
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

合併操作

x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
x
array([1, 2, 3])
y
array([3, 2, 1])
z = np.array([7, 7, 7])
# 合併
np.concatenate([x, y, z])
array([1, 2, 3, 3, 2, 1, 7, 7, 7])
# 二維數組合並
A = np.array([[1, 2, 3], [4, 5, 6]])
A
array([[1, 2, 3],
       [4, 5, 6]])
# 就是簡單的拼接
np.concatenate([A, A])
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
# 根據軸方向進行拼接,比如新的數據是在原有基礎上增加了新的屬性,而非數據疊加
# 將A和A兩個矩陣拼成一個2×6的矩陣,沿着列的維度(即第二個維度拼接)
np.concatenate([A, A], axis=1)
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])
# A是一個二維數組,z是一個一維數組,除了將z轉爲二維進行合併,還有方法
# 即使用vstack,垂直方向自動疊加
# 在裏面乘以2,表示堆疊2次
T = np.array([[1, 2, 3], [4, 5, 6]])
t = np.array([7, 7, 7])
np.vstack([T, t]*2)
array([[1, 2, 3],
       [4, 5, 6],
       [7, 7, 7],
       [1, 2, 3],
       [4, 5, 6],
       [7, 7, 7]])
# hstack水平方向疊加,注意:z是一維,這意味着根本不可能水平自動疊加
B = np.full(shape=(2,2), fill_value=22)
np.hstack([A, B])
array([[ 1,  2,  3, 22, 22],
       [ 4,  5,  6, 22, 22]])

分割

x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 分割爲三段,分別在角標3和7位置進行切割,包頭不包尾
# 注意第二個參數必須是數組
x1, x2, x3 = np.split(x, [3, 7])
x1
array([0, 1, 2])
x2
array([3, 4, 5, 6])
x3
array([7, 8, 9])
A = np.arange(16).reshape(4,4)
A
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
# 按照行分開
A1, A2 = np.split(A, [2])
A1
array([[0, 1, 2, 3],
       [4, 5, 6, 7]])
A2
array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])
# 按照列分開
A1, A2 = np.split(A, [1], axis=1)
A1
array([[ 0],
       [ 4],
       [ 8],
       [12]])
A2
array([[ 1,  2,  3],
       [ 5,  6,  7],
       [ 9, 10, 11],
       [13, 14, 15]])
## 同樣也有vsplit和hsplit
A1, A2 = np.hsplit(A, [2])
A1
array([[ 0,  1],
       [ 4,  5],
       [ 8,  9],
       [12, 13]])
A2
array([[ 2,  3],
       [ 6,  7],
       [10, 11],
       [14, 15]])
# 主要作用就是處理數據,比如我們需要將前面的特徵和最後的標籤分開
# -1表示最後一列爲基準
X, y = np.hsplit(A, [-1])
X
array([[ 0,  1,  2],
       [ 4,  5,  6],
       [ 8,  9, 10],
       [12, 13, 14]])
y
array([[ 3],
       [ 7],
       [11],
       [15]])
# 處理標籤數據,我們將其轉爲一維向量
# 即將所有行抽出,然後去第一列
y = y[:, 0]
y
array([ 3,  7, 11, 15])

四、數組運算

# 數組乘以常數
L = np.array([1, 2, 3])
L
array([1, 2, 3])
A = 2 * L
A
array([2, 4, 6])
A
array([2, 4, 6])
# 開平方
A = L ** 2
A
array([1, 4, 9], dtype=int32)
# 除法
A = L / 2
A
array([0.5, 1. , 1.5])
# 整除
A = L // 2
A
array([0, 1, 1], dtype=int32)
# 取模
A = L % 2
A
array([1, 0, 1], dtype=int32)
# 同樣適用於多維
# abs 絕對值
# cos sin tan 三角函數和反三角函數
# exp 取e自然對數的x次方
# power 去指定數的x次方
# log
# 矩陣與矩陣之間的運算
A = np.arange(4).reshape(2,2)
A
array([[0, 1],
       [2, 3]])
B = np.full(fill_value=10, shape=(2,2))
B
array([[10, 10],
       [10, 10]])
# 矩陣之間相加減
# 必須保證矩陣之間可以運算,比如2*2的就不能和3*3的加減乘
A + B
array([[10, 11],
       [12, 13]])
# 矩陣之間相乘(默認是元素一一對應)
# 但這是不對的,數學上的矩陣相乘:
# A的第一行與B的第一列對應元素相乘再求和爲第一個結果元素
# 然後A的第一行與B的第二列相乘再求和爲第二個結果元素
# B遍歷完成,再遍歷A的第二行,依次完成,所以使用dot方法
A.dot(B)
array([[10, 10],
       [50, 50]])
# 矩陣轉秩,列變行,行變列
A.T
array([[0, 2],
       [1, 3]])

向量和矩陣的運算

# 定義向量
v = np.array([1,2])
v
array([1, 2])
# np中的向量和矩陣的加減法原理:
# 將v重複堆疊和矩陣一一樣的維度,然後加減
# tile第一個參數表示要堆疊的向量,第二個參數表示在行方向堆疊兩次,列一次(相當於不堆疊)
np.tile(v, (2, 1))+A
array([[1, 3],
       [3, 5]])
# 或者使用vstack
np.vstack([v]*A.shape[0])+A
array([[1, 3],
       [3, 5]])
# 一般我們只需要直接使用【+】即可
v+A
array([[1, 3],
       [3, 5]])
# 相乘
v.dot(A)
array([4, 7])
# 如果反過來,則np會自動將向量轉爲了2*1的矩陣
A.dot(v)
array([2, 8])

求矩陣的逆

A
array([[0, 1],
       [2, 3]])
# 逆矩陣其實就是倒數A的逆與A相乘爲1
invA = np.linalg.inv(A)
invA
array([[-1.5,  0.5],
       [ 1. ,  0. ]])
invA.dot(A)
array([[1., 0.],
       [0., 1.]])
A.dot(invA)
array([[1., 0.],
       [0., 1.]])
# 這裏注意,非方陣不存在逆矩陣
P = np.arange(6).reshape(2,3)
P
array([[0, 1, 2],
       [3, 4, 5]])
# 非方陣P不存在逆矩陣,所以會報錯
invP = np.linalg.inv(P)
invP
---------------------------------------------------------------------------

LinAlgError                               Traceback (most recent call last)

<ipython-input-197-cea414d9d476> in <module>
----> 1 invP = np.linalg.inv(P)
      2 invP


<__array_function__ internals> in inv(*args, **kwargs)


D:\python\annaconda\lib\site-packages\numpy\linalg\linalg.py in inv(a)
    540     a, wrap = _makearray(a)
    541     _assert_stacked_2d(a)
--> 542     _assert_stacked_square(a)
    543     t, result_t = _commonType(a)
    544 


D:\python\annaconda\lib\site-packages\numpy\linalg\linalg.py in _assert_stacked_square(*arrays)
    211         m, n = a.shape[-2:]
    212         if m != n:
--> 213             raise LinAlgError('Last 2 dimensions of the array must be square')
    214 
    215 def _assert_finite(*arrays):


LinAlgError: Last 2 dimensions of the array must be square
# 但是我們可以求其僞逆矩陣
invP = np.linalg.pinv(P)
invP
array([[-0.77777778,  0.27777778],
       [-0.11111111,  0.11111111],
       [ 0.55555556, -0.05555556]])
P
array([[0, 1, 2],
       [3, 4, 5]])
P.dot(invP)
array([[ 1.00000000e+00, -1.11022302e-16],
       [ 2.66453526e-15,  1.00000000e+00]])

聚合操作

# 定義向量,求和
c = np.random.random(100)
c
array([0.67731747, 0.8097996 , 0.44306924, 0.10924103, 0.97039241,
       0.38847984, 0.446539  , 0.19115508, 0.89116032, 0.47422759,
       0.21237979, 0.60914912, 0.51770333, 0.40296099, 0.32301995,
       0.5885746 , 0.38878152, 0.45094951, 0.24692106, 0.5795789 ,
       0.95588068, 0.59444006, 0.28505391, 0.07476922, 0.56237941,
       0.18774368, 0.57311471, 0.13546506, 0.37562767, 0.33001114,
       0.547794  , 0.19797026, 0.25155065, 0.80938403, 0.92580965,
       0.89988772, 0.43454589, 0.02134634, 0.78510132, 0.18258255,
       0.57643742, 0.35635898, 0.76286615, 0.53281217, 0.36405572,
       0.41126815, 0.24624624, 0.11203632, 0.21297768, 0.69958934,
       0.92405496, 0.89076414, 0.35501525, 0.82317797, 0.38149612,
       0.03400909, 0.88722056, 0.4971579 , 0.02616028, 0.8918212 ,
       0.99259084, 0.28025065, 0.44650545, 0.85163306, 0.47433037,
       0.27746328, 0.84165882, 0.19512497, 0.8563142 , 0.30779172,
       0.11482631, 0.23205323, 0.1901128 , 0.89687523, 0.71286647,
       0.27232044, 0.33140446, 0.13344876, 0.47179231, 0.87548878,
       0.65723473, 0.73897465, 0.83128974, 0.78972567, 0.75736278,
       0.5927053 , 0.21856877, 0.48801456, 0.62094638, 0.95552635,
       0.24609705, 0.07953832, 0.49838666, 0.43576678, 0.29923313,
       0.48928621, 0.89216675, 0.50743572, 0.36042688, 0.90388633])
np.sum(c)
49.95480883325486
# 求最大最小值
np.min(c)
0.0213463370361493
# 矩陣
C = np.arange(16).reshape(4,-1)
C
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
# 矩陣求和
np.sum(C)
120
# 沿着第一個(行維度)進行運算,即每一列的和
# 記憶方法:axis=0,將元素壓縮到一行
np.sum(C, axis=0)
array([24, 28, 32, 36])
# axis=2,表示壓縮到一列
np.sum(C, axis=1)
array([ 6, 22, 38, 54])
# 求內積,依次相乘
np.prod(C)
0
# 求平均值
np.mean(C)
7.5
# 求中位數
np.median(C)
7.5
# 求百分位,q=50表示的就是中位數,100位最大值,0最小,有時候還要取25和75
# 方便觀察數據的分佈情況
np.percentile(c, q=50)
0.47300995170104476
np.median(c)
0.47300995170104476
for percent in (0, 25, 50, 75, 100):
    print(np.percentile(c, q = percent))
0.0213463370361493
0.27617756624264767
0.47300995170104476
0.758738621791756
0.9925908422814628
# 求方差
np.var(c)
0.07401029029118417
# 求標準差
np.std(c)
0.27204832344858176

索引

d = np.random.normal(0, 1, size=1000000)
d
array([ 0.61285995, -0.9236127 , -0.92116938, ..., -0.4371244 ,
        2.20229359,  0.48357591])
np.min(d)
-4.621589291745685
# 我們想要知道這個最小值的位置,即索引
np.argmin(d)
538778
d = np.arange(16)
d
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
# 亂序處理
np.random.shuffle(d)
d
array([ 5, 15,  1, 14, 10,  4,  7,  6, 12,  8,  0, 13,  9,  3,  2, 11])
# 排序
np.sort(d)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
# 二維矩陣
D = np.random.randint(10, size=(4,4))
D
array([[7, 3, 0, 4],
       [0, 4, 2, 1],
       [6, 5, 3, 6],
       [7, 3, 7, 3]])
# 二維矩陣的排序,sort默認是對每一行進行排序
np.sort(D)
array([[0, 3, 4, 7],
       [0, 1, 2, 4],
       [3, 5, 6, 6],
       [3, 3, 7, 7]])
# 沿着某個維度排序
np.sort(D, axis=0)
array([[0, 3, 0, 1],
       [6, 3, 2, 3],
       [7, 4, 3, 4],
       [7, 5, 7, 6]])
d
array([ 5, 15,  1, 14, 10,  4,  7,  6, 12,  8,  0, 13,  9,  3,  2, 11])
# 索引排序,依然是按照值的大小排序的,不過展示的是索引位置
# 比如原數組,最小的是0,索引爲10,所以10在第一個
np.argsort(d)
array([10,  2, 14, 13,  5,  0,  7,  6,  9, 12,  4, 15,  8, 11,  3,  1],
      dtype=int64)
 # 找到一個標點,小於其的放到左側,大於的放在右側,但是無序
np.partition(d, 3)
array([ 0,  1,  2,  3,  4,  5,  6, 15, 12,  8,  7, 13,  9, 10, 14, 11])
# 同樣也可以進行標點的索引排序
np.argpartition(d, 3)
array([10,  2, 14, 13,  5,  0,  7,  1,  8,  9,  6, 11, 12,  4,  3, 15],
      dtype=int64)
D
array([[7, 3, 0, 4],
       [0, 4, 2, 1],
       [6, 5, 3, 6],
       [7, 3, 7, 3]])
np.argsort(D, axis=1)
array([[2, 1, 3, 0],
       [0, 3, 2, 1],
       [2, 1, 0, 3],
       [1, 3, 0, 2]], dtype=int64)
np.partition(D, 3, axis=0)
array([[6, 3, 0, 1],
       [0, 3, 2, 3],
       [7, 4, 3, 4],
       [7, 5, 7, 6]])

Fancy Indexing

e = np.arange(16)
e
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
# 索引在[3,9)範圍內,步長爲2的切片
e[3:9:2]
array([3, 5, 7])
# 如果我們想指定訪問索引爲3,5,8這三個數,不是等間距
# 我們可以將索引存儲
indx = [3, 5, 8]
e[indx]
array([3, 5, 8])
# 如果我們存儲的索引是一個二維的數組
# 那麼結果也會是二維的
index = np.array([[0, 2], [1, 3]])
e[index]
array([[0, 2],
       [1, 3]])
E = e.reshape(4, -1)
E
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
# 定義行和列的索引
row = np.array([0, 1, 2])
col = np.array([1, 2, 3])
E[row, col]
array([ 1,  6, 11])
# 前兩行的
E[:2, col]
array([[1, 2, 3],
       [5, 6, 7]])
# 可以使用boolean值進行選取
col = [True, False, True, True]
E[1:3, col]
array([[ 4,  6,  7],
       [ 8, 10, 11]])

numpy的比較

e
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
e < 3
array([ True,  True,  True, False, False, False, False, False, False,
       False, False, False, False, False, False, False])
E
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
E < 6
array([[ True,  True,  True,  True],
       [ True,  True, False, False],
       [False, False, False, False],
       [False, False, False, False]])
2*E == 24 - 4 * E
array([[False, False, False, False],
       [ True, False, False, False],
       [False, False, False, False],
       [False, False, False, False]])
E != 6
array([[ True,  True,  True,  True],
       [ True,  True, False,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]])
# 計算小於等於3的個數
np.sum(E <= 3)
4
# 計算小於等於3的非0個數
np.count_nonzero(E <= 3)
4
# 判斷是否有含0元素
np.any(E == 0)
True
# 所有元素必須滿足條件才返回true
np.all(E >= 1)
False
# 沿着某個方向判斷
np.sum(E%2==0, axis=0)
array([4, 0, 4, 0])
# 必須是位運算的與或才能得到數組結果
np.sum((e % 2 == 0) | (e > 10))
11
# 查看滿足調節的具體值
# 找到每行最後一個數字可以被3整除的結果
E[E[:,3]%3==0,:]
array([[ 0,  1,  2,  3],
       [12, 13, 14, 15]])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章