1. 程式人生 > 實用技巧 >numpy讀書報告:

numpy讀書報告:

numpy 庫常見函式的介紹

<1>.numpy建立陣列

1. 從已有資料中建立陣列

  a.將列表轉換成 ndarray:

import numpy as np
ls1 = [10, 42, 0, -17, 30]
nd1 =np.array(ls1)
print(nd1)
print(type(nd1))

  執行結果:

[ 10  42   0 -17  30]
<class 'numpy.ndarray'>

  b.巢狀列表可以轉換成多維 ndarray:

import numpy as np
ls2 = [[8, -2, 0, 34, 7], [6, 7, 8, 9, 10]]
nd2 
=np.array(ls2) print(nd2) print(type(nd2))

  執行結果:

[[ 8 -2  0 34  7]
[ 6  7  8  9 10]]
<class 'numpy.ndarray'>

2. 利用 random 模組生成陣列

幾種 np.random 模組中常用的方法,如下表所示。

下面來看一些使用:

import numpy as np
import random
nd3 =np.random.random([4, 3])  #生成4行3列的陣列
print(nd3)
print("nd3的形狀為:",nd3.shape)

執行結果:

[[0.59115057 0.52022516 0.05992361]
 [0.5077815  0.81313999 0.70061259]
 [0.24654561 0.11705634 0.71399966]
 [0.73964407 0.57138345 0.89284498]]
nd3的形狀為: (4, 3)

為了每次生成同一份資料,可以指定一個隨機種子,使用 shuffle() 函式打亂生成的隨機數。

import numpy as np
np.random.seed(123)
nd4 = np.random.randn(4, 3)
print(nd4)
np.random.shuffle(nd4)
print("隨機打亂後資料:") print(nd4) print(type(nd4))

執行結果:

[[-1.0856306   0.99734545  0.2829785 ]
 [-1.50629471 -0.57860025  1.65143654]
 [-2.42667924 -0.42891263  1.26593626]
 [-0.8667404  -0.67888615 -0.09470897]]
隨機打亂後資料:
[[-1.50629471 -0.57860025  1.65143654]
 [-2.42667924 -0.42891263  1.26593626]
 [-0.8667404  -0.67888615 -0.09470897]
 [-1.0856306   0.99734545  0.2829785 ]]
<class 'numpy.ndarray'>

3.建立特定形狀的多維陣列

引數初始化時,有時需要生成一些特殊矩陣,如全是 0 或 1 的陣列或矩陣,這時我們可以利用 np.zeros、np.ones、np.diag 來實現,如下表所示。

            

下面通過幾個示例說明:

import numpy as np
# 生成全是 0 的 3x3 矩陣
nd5 =np.zeros([3, 3])
# 生成全是 1 的 3x3 矩陣
nd6 = np.ones([3, 3])
# 生成 4 階的單位矩陣
nd7 = np.eye(4)
# 生成 4 階對角矩陣
nd8 = np.diag([1, 8, 3, 10])
print("nd5 =\n", nd5)
print("nd6 =\n", nd6)
print("nd7 =\n", nd7)
print("nd8 =\n", nd8)

執行結果:

nd5 =
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
nd6 =
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
nd7 =
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
nd8 =
[[ 1  0  0  0]
[ 0  8  0  0]
[ 0  0  3  0]
[ 0  0  0 10]]


有時還可能需要把生成的資料暫時儲存到檔案中,以備後續使用。

import numpy as np
nd9 =np.random.random([3, 5])
np.savetxt(X=nd9, fname='./data.txt')
nd10 = np.loadtxt('./data.txt')
print(nd10)

執行結果:

[[0.1744383  0.15515217 0.74885812 0.57633094 0.06300636]
[0.24340527 0.65213913 0.07284238 0.52232677 0.58538849]
[0.83611286 0.76508018 0.26018483 0.20485587 0.95476232]]

開啟當前目錄下的 data.txt 也可以看到格式化的資料。

4.利用 arange() 和 linspace() 函式生成陣列

 arange() 是 numpy 模組中的函式,其格式為:

arange([start,] stop[,step,], dtype=None)

其中,start 與 stop 用來指定範圍,step 用來設定步長。在生成一個 ndarray 時,start 預設為0,步長 step 可為小數。Python 有個內建函式 range,其功能與此類似。

import numpy as np
print(np.arange(10))
print(np.arange(0, 10))
print(np.arange(1, 4, 0.5))
print(np.arange(9, -1, -1))

執行結果:

[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
[1.  1.5 2.  2.5 3.  3.5]
[9 8 7 6 5 4 3 2 1 0]

linspace() 也是 numpy 模組中常用的函式,其格式為:

np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

linspace() 可以根據輸入的指定資料範圍以及等份數量,自動生成一個線性等分向量,其中 endpoint(包含終點)預設為 True,等分數量 num 預設為 50。如果將 retstep 設定為True,則會返回一個帶步長的 ndarray。

import numpy as np
print(np.linspace(0, 1, 10))

執行結果:

[0.         0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
0.66666667 0.77777778 0.88888889 1.        ]

<2>.numpy中陣列元素的獲取

在 NumPy 中,既可以獲取 ndarray 陣列的單個元素,也可以獲取一組元素(也即切片),這與Python中的列表(list)和元組(tuple)非常類似。

import numpy as np
np.random.seed(2019)
nd1 = np.random.random([10])
# 獲取指定位置的資料, 獲取第4個元素
nd1[3]
#擷取一段資料
nd1[3:6]
# 擷取固定間隔資料
nd1[1:6:2]
# 倒序取數
nd1[::-2]
# 擷取一個多維陣列的一個區域內資料
nd2=np.arange(25).reshape([5,5])
nd2[1:3,1:3]
# 擷取一個多維陣列中, 數值在一個值域之內的資料
nd2[(nd2>3)&(nd2<10)]
# 擷取多維陣列中, 指定的行,如讀取第2,3行
nd2[[1,2]]  #或nd12[1:3,:]
# 擷取多維陣列中, 指定的列,如讀取第2,3列
nd2[:,1:3]

獲取陣列中的部分元素除了通過指定索引標籤來實現外,還可以通過使用一些函式來實現,如通過random.choice函式從指定的樣本中隨機抽取資料。





import
numpy as np from numpy import random as nr a=np.arange(1,25,dtype=float) c1=nr.choice(a,size=(3,4)) #size指定輸出陣列形狀 c2=nr.choice(a,size=(3,4),replace=False) #replace預設為True, 即可重複抽取。 #下式中引數p指定每個元素對應的抽取概率, 預設為每個元素被抽取的概率相同。 c3=nr.choice(a,size=(3,4),p=a / np.sum(a)) print("隨機可重複抽取") print(c1) print("隨機但不重複抽取") print(c2) print("隨機但按制度概率抽取") print(c3)

結果如下:

隨機可重複抽取
[[  7.  22.  19.  21.]
[  7.   5.   5.   5.]
[  7.   9.  22.  12.]]
隨機但不重複抽取
[[ 21.   9.  15.   4.]
[ 23.   2.   3.   7.]
[ 13.   5.   6.   1.]]
隨機但按制度概率抽取
[[ 15.  19.  24.   8.]
[  5.  22.   5.  14.]
[  3.  22.  13.  17.]]

<3>.NumPy的算術運算

a.對應元素相乘
對應元素相乘(Element-Wise Product)是兩個矩陣中對應元素乘積。np.multiply() 函式用於陣列或矩陣對應元素相乘,輸出與相乘陣列或矩陣的大小一致
>>> A = np.array([[1, 2], [-1, 4]])
>>> B = np.array([[2, 0], [3, 4]])
>>> A*B
array([[ 2,  0],
       [-3, 16]])
>>> np.multiply(A, B)
array([[ 2,  0],
       [-3, 16]])
b.點積運算
點積運算(Dot Product)又稱為內積,在 NumPy 中用 np.dot() 函式表示
X1=np.array([[1,2],[3,4]])
X2=np.array([[5,6,7],[8,9,10]])
X3=np.dot(X1,X2)
print(X3)

執行結果:

[[21 24 27]
 [47 54 61]]

<3>.NumPy陣列的變形

修改指定陣列的形狀是 NumPy 中最常見的操作之一,常見的方法有很多,下表列出了一些常用函式和屬性。

reshape() 函式用來改變向量的維度(不修改向量本身),請看下面的程式碼:

import numpy as np
arr =np.arange(10)
print(arr)
# 將向量 arr 維度變換為2行5列
print(arr.reshape(2, 5))
# 指定維度時可以只指定行數或列數, 其他用 -1 代替
print(arr.reshape(5, -1))
print(arr.reshape(-1, 5))

執行結果:

[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
  [5 6 7 8 9]]
[[0 1]
  [2 3]
  [4 5]
  [6 7]
  [8 9]]
[[0 1 2 3 4]
  [5 6 7 8 9]]

resize() 函式用來改變向量的維度(修改向量本身),請看下面的程式碼:

import numpy as np
arr =np.arange(10)
print(arr)
# 將向量 arr 維度變換為2行5列
arr.resize(2, 5)
print(arr)

執行如下:

[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
  [5 6 7 8 9]]

<4>.NumPy ndarray合併陣列

在 NumPy 中,合併陣列也是最常見的操作之一,下表列舉了常見的用於陣列或向量合併的方法

幾點說明:

  • append()、concatenate() 以及 stack() 都有一個 axis 引數,用於控制陣列的合併方式是按行還是按列。
  • 對於 append() 和 concatenate(),待合併的陣列必須有相同的行數或列數(滿足一個即可)。
  • stack()、hstack()、dstack() 要求待合併的陣列必須具有相同的形狀(shape)

下面選擇一些常用函式進行說明。

append() 函式可以合併一維陣列:

import numpy as np
a =np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.append(a, b)
print(c)
# [1 2 3 4 5 6]

append() 也可以合併多維陣列:

import numpy as np
a =np.arange(4).reshape(2, 2)
b = np.arange(4).reshape(2, 2)
# 按行合併
c = np.append(a, b, axis=0)
print('按行合併後的結果')
print(c)
print('合併後資料維度', c.shape)
# 按列合併
d = np.append(a, b, axis=1)
print('按列合併後的結果')
print(d)
print('合併後資料維度', d.shape)

執行如下:

按行合併後的結果
[[0 1]
  [2 3]
  [0 1]
  [2 3]]
合併後資料維度 (4, 2)
按列合併後的結果
[[0 1 0 1]
  [2 3 2 3]]
合併後資料維度 (2, 4)

concatenate() 沿指定軸連線陣列或矩陣:

import numpy as np
a =np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c = np.concatenate((a, b), axis=0)
print(c)
d = np.concatenate((a, b.T), axis=1)
print(d)

執行如下:

[[1 2]
  [3 4]
  [5 6]]
[[1 2 5]
  [3 4 6]]

stack() 沿指定軸堆疊陣列或矩陣:

import numpy as np
a =np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(np.stack((a, b), axis=0))

執行如下:

[[[1 2]
  [3 4]]

[[5 6]
  [7 8]]]

<5>.NumPy ufunc通用函式

NumPy 的 Universal functions 中要求輸入的陣列 shape 是一致的,當陣列的 shape 不相等時,則會使用廣播機制。
不過,調整陣列使得 shape 一樣,需要滿足一定的規則,否則將出錯。
這些規則可歸納為以下 4 條。

1) 讓所有輸入陣列都向其中 shape 最長的陣列看齊,不足的部分則通過在前面加 1 補齊

2) 輸出陣列的 shape 是輸入陣列 shape 的各個軸上的最大值。

3) 如果輸入陣列的某個軸和輸出陣列的對應軸的長度相同或者某個軸的長度為 1 時,這個陣列能被用來計算,否則出錯。

4) 當輸入陣列的某個軸的長度為 1 時,沿著此軸運算時都用(或複製)此軸上的第一組值。

import numpy as np
A = np.arange(0, 40,10).reshape(4, 1)
B = np.arange(0, 3)
print("A矩陣的形狀:{},B矩陣的形狀:{}".format(A.shape,B.shape))
C=A+B
print("C矩陣的形狀:{}".format(C.shape))
print(C)

執行如下:

A矩陣的形狀:(4, 1),B矩陣的形狀:(3,)
C矩陣的形狀:(4, 3)
[[ 0  1  2]
  [10 11 12]
  [20 21 22]
  [30 31 32]]