【Python】Numpy簡單入門
阿新 • • 發佈:2019-01-08
Numpy
Numpy是Python中科學計算的核心庫。Numpy提供了高效能的多維陣列物件,還有用於處理這些陣列的工具。
陣列
Numpy的主要資料型別是ndarray即多維陣列,可以用巢狀的Python列表中初始化numpy陣列,並使用方括號訪問元素。陣列具有以下幾個屬性:
- ndarray.ndim: 陣列的維數
- ndarray.shape: 陣列每一維的大小
- ndarray.size: 陣列中全部元素的數量
- ndarray.dtype: 陣列中元素的型別(numpy.int32, numpy.int16, and numpy.float64等)
- ndarray.itemsize:每個元素佔幾個位元組
陣列操作
import numpy as np # 匯入numpy模組 a = np.array([1,2,3]) print(type(a)) # a的型別是numpy.ndarray print(a.shape) # 一維陣列,列向量 print(a[0],a[1],a[2]) # 下標從0開始計數 a[0] = 5 # 修改陣列元素的值 print(a) b = np.array([[1,2,3],[4,5,6]]) print(b.shape) # 二維陣列,2×3 print(b[0,0],b[0,1],b[1,0]) # 二維陣列下標 c = np.array([1,]) # 一維陣列 print(c.shape)
執行結果
<class 'numpy.ndarray'>
(3,)
1 2 3
[5 2 3]
(2, 3)
1 2 4
(1,)
建立陣列
import numpy as np a = np.zeros((2,2)) # 2×2全零陣列 print(a) b = np.ones((1,2)) # 2×2全一陣列 print(b) c = np.full((2,2),7) # 2×2常量陣列,執行結果是‘7’而不是‘7.’ print(c) d = np.eye(2) # 2×2單位陣列 print(d) e = np.random.random((2,2)) # 2×2隨機陣列,範圍為[0,1] print(e)
執行結果
[[ 0. 0.]
[ 0. 0.]]
[[ 1. 1.]]
[[7 7]
[7 7]]
[[ 1. 0.]
[ 0. 1.]]
[[ 0.75674195 0.00198805]
[ 0.0375324 0.72334415]]
陣列索引
Numpy提供了幾種索引陣列的方法。
切片
類似於Python中的列表List,可以將numpy陣列進行切片。如果是多維陣列,需要為陣列的每個維度指定一個切片。
import numpy as np
a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
b = a[:2,1:3]
print(a)
print(b)
print(a[0,1]) # 第一行第二個
b[0,0] = 77 # a、b共用同一資料
print(a[0,1])
a[0,1] = 60 # 改變a或b,都會改動另一方,類似C++中引用
print(b[0,0])
執行結果
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[2 3]
[6 7]]
2
77
60
整型索引與切片索引混合
這個做法會產生比原始陣列更低階的陣列。
import numpy as np
a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
row_r1 = a[1,:] # 產生一維陣列
row_r2 = a[1:2,:] # 產生二維陣列
print(row_r1,row_r1.shape)
print(row_r2,row_r2.shape)
col_r1 = a[:,1]
col_r2 = a[:,1:2]
print(col_r1,col_r1.shape)
print(col_r2,col_r2.shape)
執行結果
[5 6 7 8] (4,)
[[5 6 7 8]] (1, 4)
[ 2 6 10] (3,)
[[ 2]
[ 6]
[10]] (3, 1)
整數陣列索引
當對numpy陣列使用切片索引時,生成的陣列將始終是原始陣列的子陣列。而整數陣列索引則允許使用另一個數組的資料構造任意的陣列。
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
print(a[[0,1,2],[0,1,0]]) # 行、列
print(np.array([a[0,0],a[1,1],a[2,0]])) # 每個的座標
b = np.array([0,2,0,1])
print(a[np.arange(4),b])
a[np.arange(4),b] += 10
print(a)
執行結果
[1 5 7]
[1 5 7]
[ 1 6 7 11]
[[11 2 3]
[ 4 5 16]
[17 8 9]
[10 21 12]]
布林陣列索引
布林陣列索引可挑選出一個數組的任意元素。通常,這種型別的索引用於選擇滿足某些條件的陣列的元素。
import numpy as np
a = np.array([[1,2],[3,4],[5,6]])
bool_idx = (a > 2) # 逐個比較
print(bool_idx)
print(a[bool_idx])
print(a[a > 2])
執行結果
[[False False]
[ True True]
[ True True]]
[3 4 5 6]
[3 4 5 6]
資料型別
import numpy as np
x = np.array([1,2]) # int64
print(x,x.dtype)
x = np.array([1.0,2.0]) # float64
print(x,x.dtype)
x = np.array([1.5,2.8],dtype = np.int64) # 強制轉換,int64
print(x,x.dtype)
執行結果
[1 2] int32
[ 1. 2.] float64
[1 2] int64
陣列計算
陣列可以進行基本的數學函式計算,並且可以作為操作符過載和在numpy模組中的函式。
import numpy as np
x = np.array([[1,2],[3,4]],dtype = np.float64)
y = np.array([[5,6],[7,8]],dtype = np.float64)
print(x + y) # 加法
print(np.add(x,y))
print(x - y) # 減法
print(np.subtract(x,y))
print(x * y) # 乘法
print(np.multiply(x,y))
print(x / y) # 除法
print(np.divide(x,y))
print(np.sqrt(x)) # 開方
print(np.sum(x)) # 所有元素相加
print(np.sum(x,axis = 0)) # 列向量相加
print(np.sum(x,axis = 1)) # 行向量相加
v = np.array([9,10])
w = np.array([11,12])
print(x.T) # 多維陣列轉置
print(v.T) # 一維陣列轉置不發生改變
print(v.dot(w)) # 計算內積
print(np.dot(v,w))
print(np.dot(x,v))
print(np.dot(x,y))
執行結果
[[ 6. 8.] # 加法
[ 10. 12.]]
[[ 6. 8.]
[ 10. 12.]]
[[-4. -4.] # 減法
[-4. -4.]]
[[-4. -4.]
[-4. -4.]]
[[ 5. 12.] # 乘法
[ 21. 32.]]
[[ 5. 12.]
[ 21. 32.]]
[[ 0.2 0.33333333] # 除法
[ 0.42857143 0.5 ]]
[[ 0.2 0.33333333]
[ 0.42857143 0.5 ]]
[[ 1. 1.41421356] # 開方
[ 1.73205081 2. ]]
10.0 # 所有元素相加
[ 4. 6.] # 列向量相加
[ 3. 7.] # 行向量相加
[[ 1. 3.] # 多維陣列轉置
[ 2. 4.]]
[ 9 10] # 一維陣列轉置不發生改變
219 # 計算內積v.dot(w)
219 # 計算內積np.dot(v,w)
[ 29. 67.] # 計算內積np.dot(x,v)
[[ 19. 22.] # 計算內積np.dot(x,y)
[ 43. 50.]]
Broadcasting
Broadcasting廣播機制是Python中一種強大的機制,它允許numpy在執行算術運算時使用不同形狀的陣列。當對一個較小的陣列和一個較大的陣列進行運算時,通過多次使用較小的陣列來對較大的陣列執行一些操作。
import numpy as np
x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
v = np.array([1,0,1])
y_empty = np.empty_like(x) # 建立一個與x大小相同的空矩陣
for i in range(4):
y_empty[i,:] = x[i,:] + v;
print(y_empty)
vv = np.tile(v,(4,1)) # 將v垂直地堆疊起來,形成新陣列vv,比上一種方法執行速度快
print(vv)
y_tile = x + vv
print(y_tile)
y_bc = x + v # 傳播機制BoardCasting
print(y_bc)
執行結果
[[ 2 2 4] # y_empty
[ 5 5 7]
[ 8 8 10]
[11 11 13]]
[[1 0 1] # vv
[1 0 1]
[1 0 1]
[1 0 1]]
[[ 2 2 4] # y_tile
[ 5 5 7]
[ 8 8 10]
[11 11 13]]
[[ 2 2 4] # y_bc
[ 5 5 7]
[ 8 8 10]
[11 11 13]]