Numpy
1.基本操作
1.1數組轉換
創建數組的最簡單的方法就是使用array函數,將Python下的list轉換為ndarray
#通過數組創建一個ndarray
data1 = [6,7.5,8,0,1]
arr1 = np.array(data1)
arr1
#輸出為:
array([6,7.5,8,0,1])
創建二維數組
#通過數組創建一個二維的ndarray
data2 = [[1,2,3,4],[5,6,7,8]]
arr2 = np.array(data2)
arr2
#輸出為:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
重新定義矩陣的形狀
array.reshape((n,m))
1.2數組生成
除了通過數組轉換而來之外,我們可以利用np中的一些內置函數來創建數組,比如我們創建全0的數組,也可以創建全1數組,或者等差數列數組
創建全0數組
np.zeros(10)
#輸出為:
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
創建全1數組
np.ones(10)
#輸出為:
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
創建元素接近空的數組
np.empty((3,4))
#輸出為:
array([[4.9e-324, 4.9e-324, 9.9e-324, 9.9e-324],
[9.9e-324, 9.9e-324, 9.9e-324, 1.5e-323],
[2.0e-323, 2.0e-323, 2.5e-323, 2.5e-323]])
注:創建初始是隨機數,而不是空,需要重新賦值
創建等差數組
np.arange(1,15,2)
#輸出為:
array([ 1, 3, 5, 7, 9, 11, 13])
創建正態分布隨機數組
samples = np.random.normal(2,3,size=(4,4))
samples
#輸出為:
array([[ 6.15721917, 3.42393052, 0.65418836, -0.6927128 ],
[ 2.79557529, 1.1205289 , 1.63283966, 6.18085827],
[-1.02241948, -2.77444011, -0.7293639 , 1.9849088 ],
[ 2.52981105, 1.80517346, -1.98852316, 1.71483645]])
創建正態分布數組
samples = np.random.randn(4,4)
samples
#輸出為:
array([[-0.96184087, 0.86026662, 1.13674982, 2.74464916],
[ 0.14419425, -0.57185231, 0.61601683, -0.18976333],
[-0.25594082, -1.84514383, 0.54483433, 1.77408903],
[-0.16996494, 0.18802037, 1.54856742, 0.18296107]])
randint生成隨機整數數組
samples = np.random.randint(0,10,size=(3,4))
samples
#輸出為:
array([[6, 7, 2, 2],
[1, 3, 5, 6],
[5, 8, 4, 9]])
1.3文件讀取
save方法保存ndarray到一個npy文件,也可以使用savez將多個array保存到一個.npz文件中:
x = np.array([1,2,4,5])
y = np.array([3,4,5])
#save方法可以存取一個ndarray
np.save("x_arr",x)
#如果要存取多個數組,要是用savez方法
np.savez("some_array.npz",xarr = x,yarr=y)
load方法來讀取存儲的數組,如果是.npz文件的話,讀取之后相當於形成了一個k-v類型的變量,通過保存時定義的key來獲取相應的array。
np.load('x_arr.npy')
#array([1, 2, 4, 5])
arch = np.load("some_array.npz")
arch['yarr']
#array([3, 4, 5])
np.loadtxt 和 np.savetxt可以用來存取txt或csv文件
arr=[[6, 7, 2, 2],
[1, 3, 5, 6],
[5, 8, 4, 9]]
#儲存數組到txt文件
np.savetxt("array_ex.txt",arr)
#讀取txt文件,delimiter為分隔符,dtype為數據類型
np.loadtxt("array_ex.txt",delimiter=" ",dtype=np.int32)
1.4查看操作
查看維度
array.ndim
查看形狀
array.shape
查看元素個數
array.size
2.數據類型
ndarray的數據類型:
- int: int8、int16、int32、int、64
- float: float16、float32、float64
- string
2.1指定數據類型:
#指定array的數據類型
arr1 = np.array([1,2,3],dtype=np.int32)
arr2 = np.array([1,2,3],dtype=np.float32)
輸出為:
#arr1
array([1, 2, 3], dtype=int32)
#arr2
array([1., 2., 3.], dtype=float32)
2.2查看數據類型
#查看array的數據類型
arr2.dtype
### dtype('float32')
2.3數據類型轉換
使用astype將一個數組的數據類型進行轉換,這樣會返回一個新的數組,對原數組不會產生影響
#數據類型進行轉換,會產生一個新的array,原array不產生影響
arr1.astype(np.float32)
arr1.dtype
# dtype('int32')
如果一個數組中的字符串只含有數字,可以將string轉換為數值形式:
numeric_strings = np.array(['1.25','0.96','42'],dtype=np.string_)
numeric_strings.astype(np.float32)
# array([ 1.25 , 0.95999998, 42. ], dtype=float32)
3.數組運算
3.1數組間運算
大小相等的數組之間的任何算數運算都會應用到元素身上
arr = np.array([[1,2,3],[4,5,6]],dtype=np.float32)
arr * arr
#array([[ 1., 4., 9.],
# [ 16., 25., 36.]], dtype=float32)
arr - arr
#array([[ 0., 0., 0.],
# [ 0., 0., 0.]], dtype=float32)
不同維度數組間的計算,低維數組每個元素分別與高維數組計算
a = np.array([[1,2,3,4],[6,7,8,9]])
b = np.arange(1,5)
print(a+b)
# array([[ 2, 4, 6, 8],
[ 7, 9, 11, 13]])
print(a*b)
# array([[ 2, 4, 6, 8],
[ 7, 9, 11, 13]])
print(a/b)
# array([[ 2, 4, 6, 8],
[ 7, 9, 11, 13]])
3.2數組與標量
數組與標量的算術運算也會將標量值傳播到各個元素:
1 / arr
#array([[ 1. , 0.5 , 0.33333334],
# [ 0.25 , 0.2 , 0.16666667]], dtype=float32)
4.索引和切片
4.1基本索引和切片
numpy中數組切片是原始數組的視圖,這意味着數據不會被復制,視圖上任何數據的修改都會反映到原數組上。
arr = np.arange(10)
arr[5]
# 5
arr[5:8]
#array([5, 6, 7])
arr[5:8]=12 #切片賦值會賦值到每個元素上,與列表操作不同
t = arr[5:8]
t[1] = 12345
arr
#array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
使用copy方法,可以看到使用copy之后再修改數據不會影響到原數據:
t1 = arr[5:8].copy()
t1[2] = -222
arr
#array([ 0, 1, 2, 3, 4, 64, 64, 64, 8, 9])
對於二維數組或者高維數組,我們可以按照之前的知識來索引,當然也可以傳入一個以逗號隔開的索引列表來選區單個或多個元素
arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
arr2d[0,2] #(等於arr2d[0][2])
#3
arr2d[:2,1:] #等於arr2d[:2][:,1:]
#array([[2, 3],
# [5, 6]])
4.2布爾型索引
names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
data = np.random.randn(7,4)
names == 'Bob'
#array([ True, False, False, True, False, False, False], dtype=bool)
data[names=='Bob']
#array([[ 0.75323688, 0.85622553, -2.71974541, 0.37865467],
# [ 1.35356641, 0.09263267, 1.96207471, -0.05549953]])
布爾型索引邏輯運算,“|” 表示或 “&”表示 與
data[(names=='Bob')| (names=='Will')]
#array([[ 0.75323688, 0.85622553, -2.71974541, 0.37865467],
[ 0.93720776, -1.49360063, -0.06471438, 0.62149438],
[ 1.35356641, 0.09263267, 1.96207471, -0.05549953],
[ 1.87344915, 1.75085643, 1.9197879 , 0.47687361]])
4.3花式索引
花式索引的方式,它指利用整數數組進行索引,花式索引和切片不一樣,它總是將數據復制到新數組中
arr = np.empty((8,4))
for i in range(8):
arr[i] = i
arr[[4,3,0,6]]
輸出為:
array([[ 4., 4., 4., 4.],
[ 3., 3., 3., 3.],
[ 0., 0., 0., 0.],
[ 6., 6., 6., 6.]])
選擇一塊方形區域,同時按照我們指定的順序排列數據,我們嘗試以下的方式:
arr = np.arange(32).reshape((8,4))
arr[[1,5,7,2],[0,3,1,2]]
輸出為:
array([ 4, 23, 29, 10])
這是因為按照上面的方式進行選取,會將選擇出的元素鎖定在4個元素上。
正確的方式有下面兩種:
arr[[1,5,7,2]][:,[0,3,1,2]]
arr[np.ix_([1,5,7,2],[0,3,1,2])]
輸出為:
array([[ 4, 7, 5, 6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])
5.數組轉置和軸對換
轉置T屬性:
arr = np.arange(15).reshape((5,3))
arr.T
#array([[ 0, 3, 6, 9, 12],
[ 1, 4, 7, 10, 13],
[ 2, 5, 8, 11, 14]])
對於高維數組,tranpose需要得到一個由軸編號組成的元組才能對這些軸進行轉置,太費腦子:
arr.transpose((1,0,2))
#array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
6.數組函數
6.1通用函數:元素級數字函數
- 一元函數:
abs 絕對值
sqrt 開方
square 平方根
exp e的冪次方
log 對數函數
sin/cos/tan 三角函數
- 二元函數:
maxinmum 最大值
minimum 最小值
arr = np.arange(10)
np.sqrt(arr)
x = np.random.randn(8)
y = np.random.randn(8)
np.maximum(x,y)
#array([ 0.68417031, 0.22971426, 1.69724546, 1.19366822, -0.79176777, -0.43557768, 0.66628223, 0.85093113])
6.2where函數
where 函數,三個參數,條件為真時選擇值的數組,條件為假時選擇值的數組:
xarr = np.array([1.1,1.2,1.3,1.4,1.5])
yarr = np.array([2.1,2.2,2.3,2.4,2.5])
cond = np.array([True,False,True,True,False])
np.where(cond,xarr,yarr)
輸出為:
array([ 1.1, 2.2, 1.3, 1.4, 2.5])
也可以使用下面的形式,后兩個參數為指定值:
np.where(xarr>1.2,2,-2)
#array([-2, -2, 2, 2, 2])
6.3數學和統計方法
數學和統計方法既可以當作數組的實例方法調用,也可以當作numpy函數調用,比如下面兩種計算數組均值的方法是等效的:
arr = np.random.randn(5,4)
arr.mean()
np.mean(arr)
mean,sum,max,min這一類函數可以接受一個axis參數,用於計算該軸向上的統計值,最終結果是一個少一維的數組。對於一個二維數組,axis=0相當於按列操作,最終元素的個數和第二維的大小相同,axis=1相當於按行操作,最終元素的個數和第一維的大小相同:
arr.mean(axis=1)
#array([ 0.29250253, -0.50119163, 0.11746254, 0.23338843, 0.15912472])
arr.sum(0)
#array([ 1.92728592, 0.67480797, -2.8398905 , 1.44294295])
我們也可以用cumsum(累加值計算)和cumprod(累積值計算)保留中間計算結果:
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
arr.cumsum(0)
#array([[ 1, 2, 3],
[ 5, 7, 9],
[12, 15, 18]])
arr.cumprod(1)
#array([[ 1, 2, 6],
[ 4, 20, 120],
[ 7, 56, 504]])
6.4排序方法
np中還提供了排序方法,排序方法是就地排序,即直接改變原數組:
arr = np.random.randn(8)
arr
#array([-0.85668922, -2.0049649 , -0.89885165, -0.04185277, 0.73736138,-0.03509021, -1.89745107, -2.36576122])
arr.sort()
arr
#array([-2.36576122, -2.0049649 , -1.89745107, -0.89885165, -0.85668922,-0.04185277, -0.03509021, 0.73736138])
6.5集合運算函數
unique計算x中的唯一元素,並返回有序結果
arr = np.array([1,3,2,5,2,4,2,2,1,4,5,2])
np.unique(arr)
#array([1, 2, 3, 4, 5])
numpy提供了下面三個常見的集合運算函數:
intersect1d(x,y) 用於計算x和y的公共結果,並返回有序結果
union1d(x,y) 用於計算x和y的並集,並返回有序結果
setdiff1d(x,y),集合的差,即元素在x中不在y中
x = np.array([1,2,4,5])
y = np.array([3,4,5])
np.intersect1d(x,y)
#array([4, 5])
np.union1d(x,y)
#array([1, 2, 3, 4, 5])
np.setdiff1d(x,y)
#array([1, 2])
線性代數
矩陣的乘積
#矩陣的乘積
x = np.array([[1,2,3],[4,5,6]])
y = np.array([[6,23],[-1,7],[8,9]])
np.dot(x,y)
下面可以計算矩陣的逆、行列式、特征值和特征向量、qr分解值,svd分解值:
#計算矩陣的逆
from numpy.linalg import inv,det,eig,qr,svd
t = np.array([[1,2,3],[2,3,4],[4,5,6]])
inv(t)
#計算矩陣行列式
det(t)
#計算QR分解址
qr(t)
#計算奇異值分解值svd
svd(t)
#計算特征值和特征向量
eig(t)