numpy是一個科學計算庫,專門用于矩陣,可以代替matlab的一些矩陣操作與計算。本篇内容的原型為某站200集AI教程的學習所得,後來經過部落客結合其他部落格,深化學習,産生了本篇博文。
文章目錄
- 環境介紹
- numpy的IO庫
- numpy建立矩陣
- shape列印矩陣形狀
- dtype列印矩陣裡面元素的類型
- numpy索引讀取資料
- numpy切片
- 對numpy.array中所有元素做整體操作
- bool值當索引
- 矩陣元素的與、或條件篩選
- 矩陣元素的類型轉換
- 矩陣求極值
- 求和(按照行或者列)
- 指數計算/開平方根
- 初始化0矩陣和1矩陣
- 矩陣的操作
- reshape重置矩陣的形狀
- 矩陣的橫向縱向拼接
- 矩陣的橫向縱向切割
- 關于矩陣複制
- 指派符号
- 淺複制
- 深複制
- 排序和索引
- 最值
- 擴充
- 排序
- 總結
- 參考資料
環境介紹
整個博文是在anaconda平台上基于python3.7實作的。
numpy的IO庫
numpy提供了下列的IO函數:
save():将ndarray對象儲存為.npy檔案,為二進制檔案
load():從.npy檔案中擷取ndarray對象
savetxt():将ndarray對象儲存為.txt檔案
loadtxt():從.txt檔案中擷取ndarray對象
簡單用代碼實作一下:
# 案例1,模拟讀取txt
```python
from io import StringIO
import numpy as np
s = StringIO(u"1,1.3,abcde")
data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'), ('mystring','S5')], delimiter=",")
data
輸出:
array((1, 1.3, b’abcde’),dtype=[(‘myint’, ‘<i8’), (‘myfloat’, ‘<f8’), (‘mystring’, ‘S5’)])
#案例2 ,真實讀取txt檔案,txt檔案要規範,比如換行規範+用,隔開。
import numpy
world_alcohol = numpy.genfromtxt("word_alcohol.txt", delimiter=",",dtype=str)
#上面一句話是:執行個體化一個numpy.genfromtxt的對象,第一參數傳要讀取的檔案名,第二個是分割符(每一行看作一條資料,逗号區分每個資料的屬性),最 #後一個讀取後的資料類型。這是用numpy.genfromtxt讀取txt檔案内容的方法。如果實際類型是時間,可以讀進來再轉化。
print(type(world_alcohol)) # <class 'numpy.ndarray'>
print(world_alcohol) # 列印ndarray對象的内容
print(help(numpy.genfromtxt)) # help函數,解釋參數函數的用法。
#案例3,讀取txt中的資料,且按照對應的格式,讀取出來是一個對象清單,也可以了解為是一個一維矩陣
import numpy as np
data = np.genfromtxt("word_alcohol.txt", dtype=[('myint','i8') ,('mystring1','S5'), ('mystring2','S5') ,('mystring3','S5'),('myfloat','f8')], delimiter=",",skip_header=1)
#data = np.genfromtxt("word_alcohol.txt", delimiter=",",dtype=str,skip_header=1)
print(data)
#print(help(np.genfromtxt))
列印輸出:
array([(1986, b'Weste', b'Viet ', b'Wine', 0. ),
(1986, b'Ameri', b'Urugu', b'Other', 0.5)],
dtype=[('myint', '<i8'), ('mystring1', 'S5'), ('mystring2', 'S5'), ('mystring3', 'S5'), ('myfloat', '<f8')])
numpy建立矩陣
如何利用numpy架構建立一個矩陣。
vector = numpy.array([5, 10, 15, 20]) #使用numpy.array方法把一個list轉化為一個向量或者叫一行矩陣。
matrix = numpy.array([[5, 10, 15], [20, 25, 30], [35, 40, 45]]) #使用numpy.array方法把多個list轉化為一個矩陣。
print(vector)
print(matrix)
總結:是以寫一維矩陣寫一個中括号,寫二維矩陣寫二個中括号,寫三維矩陣寫三個中括号。
shape列印矩陣形狀
vector = numpy.array([5, 10, 15, 20])
print(vector.shape) #vector.shape就是列印該矩陣的形狀,即幾維,幾行幾列。
matrix = numpy.array([[5, 10, 15], [20, 25, 30], [35, 40, 45]])
print(matrix.shape) #matrix.shape就是列印該矩陣的形狀,即幾維,幾行幾列。
一般XXX.shape用作調試程式用。可以直接輸出。
輸出:
(4,) # 一行四列
(3, 3) # 3行3列 2維
在numpy的矩陣中,不像是list,你想放什麼就放什麼,是有格式要求的。裡面必須是相同的結構,
dtype列印矩陣裡面元素的類型
建構numpy矩陣時,要求裡面的元素都是一樣的類型,如果已有的整型/字元型/浮點型,滿足不了需要,可以在讀取的時候定義讀取單個資料的dtype。就好像上面的讀取txt文檔的例子,不過這種定義dtype的類型一般讀出來就是一維矩陣,類似一個java中list。
numbers = numpy.array([1, 2, 3, 4])
print(numbers)
print(numbers.dtype)
輸出:
[1 2 3 4]
int32
當上述代碼修改成下面時:
numbers = numpy.array([1, 2, 3, 4.0])
print(numbers)
print(numbers.dtype)
輸出:
[ 1. 2. 3. 4.]
float64
如果其中一個改成字元串,那麼最終的類型就是都是字元串。因為矩陣裡面的類型要一緻這個規則的限制,如果矩陣裡面元素的基本類型不統一,會自動轉型為進階類型,轉型順序:int < float < string。
numpy索引讀取資料
import numpy
world_alcohol = numpy.genfromtxt("world_alcohol.txt", delimiter=",", dtype="U75", skip_header=1)
print(world_alcohol)
uruguay_other_1986 = world_alcohol[1,4] #我們需要取的資料是第2行第5個,同list第一個資料索引值為0
third_country = world_alcohol[2,2] #這行我們需要取的資料是第3行第3個。
print(uruguay_other_1986)
print(third_country)
需要注意的是索引從0開始,用中括号讀取,第一個數字是第一個次元,第n個數字是第n個次元。
輸出:
0.5
Cte d’Ivoire
numpy切片
切片,是把已有的矩陣取出來一個區域,待操作的矩陣可以是一維的也可以是多元的。
切片的規則:顧頭不顧腚,即包含起始位置,不包含結束位置。
1)向量的切片
vector = numpy.array([5, 10, 15, 20]) #建立一個向量
print(vector[0:3]) #向量與list的切片方式一緻,顧頭不顧尾。也就是取0-1-2位置的三個數字。
輸出:
[ 5 10 15]
2)矩陣的單列或單行切片,技巧使用冒号表示所有行或者列,也就是說可以單獨拿出來某一行或者某一列。
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
]) #建立矩陣
print(matrix[:,1]) # :表示這一行或一列的所有元素。以“,”為間隔,隔開行和列的位置(這裡要區分索引用分号控制下标)。如果在第一個位置為行,第二個位置為列。
輸出:
[10 25 40]
3)矩陣的多列或多行切片,采用切片的規則,顧頭不顧腚
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
print(matrix[:,0:2]) #以","為間隔,隔開行和列的位置。":"表示所有元素。 截取所有行的0和1列,這是做的切片,顧頭不顧尾
輸出:
[[ 5 10]
[20 25]
[35 40]]
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
print(matrix[1:3,0:2])
# 截取第1-2行,第0-1列
輸出:
[[20 25]
[35 40]]
對numpy.array中所有元素做整體操作
對numpy.array整體的操作=對numpy.array每一個元素做相同的操作。用變量做大于小于等于的操作,就可以得出矩陣裡每個元素比較結果的矩陣。
vector = numpy.array([5, 10, 15, 20])
print(vector == 10)
output:
[False True False False]
這一條定律對矩陣一樣适用:
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
print(matrix == 25)
output:
[[False False False]
[False True False]
[False False False]]
總結:可以把比較的結果設定成一個變量,這樣就能取出對應的符合條件的值了。
bool值當索引
上面的例子我們篩選出了符合條件的資料,形成了一個篩選結果矩陣。但是如何把這些符合篩選條件的元素取出來。
可以用bool值當索引。
方法:把某個矩陣的對應布爾值矩陣作為索引傳遞給原矩陣,則會傳回出bool值為真的元素
vector = numpy.array([5, 10, 15, 20])
equal_to_ten = (vector == 10)
print(equal_to_ten)
print(vector[equal_to_ten])
output:
[False True False False]
[10]
上述規律對矩陣一樣适用: 定位列之後,拿出來那一行的寫法
matrix = np.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
second_column_25 = (matrix[:,1] == 25) #單獨拿出第1列與25比較,找出等于25的值
print(second_column_25)
print(matrix[second_column_25, :]) #會選出為true的那一行,second_column_25是所在的行号,:是取出該行的所有列
output:
[False True False]
[[20 25 30]]
矩陣元素的與、或條件篩選
1)bool值表的與,,用“&”表示
vector = numpy.array([5, 10, 15, 20])
#即等于10 又等于 5
equal_to_ten_and_five = (vector == 10) & (vector == 5)
print(equal_to_ten_and_five)
output:
[False False False False]
2)bool值表的或,用“|”表示
vector = numpy.array([5, 10, 15, 20])
#等于10 或者 等于 5
equal_to_ten_and_five = (vector == 10) | (vector == 5)
print(equal_to_ten_and_five)
結果:
[True True False False]
矩陣元素的類型轉換
字元串在符合規則的情況下,可以轉換為int或者float類型。
vector = np.array(["11", "2", "3"])#元素為字元串類型
print(vector.dtype)#列印元素類型 python 3 需要括号
print(vector)
vector = vector.astype(float)#用astype()方法進行強制類型轉換。
print (vector.dtype)
print (vector)
輸出結果:
<U2 #數字代表字元串的長度,可以這麼了解,unicode2
[‘11’ ‘2’ ‘3’]
float64
[11. 2. 3.]
矩陣求極值
獲得矩陣的最大值,最小值。
vector = np.array([5, 10, 15, 20])
print(vector.min())#求矩陣中最小的元素
print(vector.max()) #求矩陣中最小的元素
#print(help(np.array))#想了解更多的方法或函數,列印相關幫助即可
求和(按照行或者列)
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
matrix.sum(axis=1) #按行求和,參數axis=1
#output:array([ 30, 75, 120])
matrix.sum(axis=0) #按列求和,參數axis=0
#output:array([60, 75, 90])
指數計算/開平方根
B = np.arange(3)# 生成一個[0 1 2]的一維矩陣,3為結束項
print(B)
print (np.exp(B))#exp是以e為底數,B的每個元素分别作為指數進行計算,計算結果以矩陣的方式顯示
print (np.sqrt(B))#sqrt是對B的每個元素分别開根号,計算結果以矩陣的方式顯示
輸出結果:
[0 1 2]
[1. 2.71828183 7.3890561 ]
[0. 1. 1.41421356]
初始化0矩陣和1矩陣
可以利用numpy提供的api快速初始化指定次元的0矩陣和1矩陣,也就是矩陣的元素是0或者1.
zero_array = np.zeros((3,4))
print(zero_array)
one_array = np.ones((3,4),dtype=int)
print(one_array)
輸出0矩陣或者1矩陣。如下:
[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]
矩陣的操作
a = np.floor(10*np.random.random((3,4))) #np.random.random((3,4)) 是0到1之間的随機浮點數3行4列,*10讓資料擴大10倍便于分辨,floor方法是向下取整又叫舍尾法近似。
print(a)
print("----")
print(a.ravel())#a.ravel() 方法是把一個二維矩陣拉伸成一個1維向量,順序是先第1行從左到右,然後第2行從左到右,以此類推
print("----")
a.shape = (6, 2)#把矩陣a的形狀設定為6行2列
print(a)
print("----")
print(a.T)#把a矩陣轉置,即把原來的第一列變為新矩陣的第一行,第二列變為新矩陣的第二行,即原來的行變為列,原來的列變為行,依次類推。
代碼的輸出為:
reshape重置矩陣的形狀
print("----")
#reshape(3,-1)方法是修改矩陣的形狀,3是3行,-1這個數表示讓計算機根據其他次元的資料.
#自動算出-1這個地方應該填寫多少,并完成修改。矩陣的拼接:
print(a.reshape(3,-1))
代碼的輸出:
矩陣的橫向縱向拼接
主要是np的兩個常用函數hstack,vstack。
a = np.floor(10*np.random.random((2,2)))
b = np.floor(10*np.random.random((2,2)))
print("------")
print(a)
print("------")
print(b)
print("------")
print(np.hstack((a,b)))# hstack方法是矩陣橫向拼接方法
print("------")
print(np.vstack((a,b)))# hstack方法是矩陣縱向拼接方法
print("------")
代碼的輸出為:
------
[[5. 5.]
[2. 5.]]
------
[[6. 4.]
[5. 7.]]
------
[[5. 5. 6. 4.]
[2. 5. 5. 7.]]
------
[[5. 5.]
[2. 5.]
[6. 4.]
[5. 7.]]
------
矩陣的橫向縱向切割
矩陣的切分:
a = np.floor(10*np.random.random((2,12)))
print(a)
print("------")
print (np.hsplit(a,3))# hsplit函數是橫向切割,傳入兩個參數,第一個參數是要被切割的矩陣,第二個是切成幾份。
print("------")
print (np.hsplit(a,(3,4)))# hsplit還有一種用法,指定在某幾個位置切。該例子中,第二個位置參數是一個元組形式,表示在位置3,4分别切一刀
print("-----分割線----")
a = np.floor(10*np.random.random((12,2)))
print(a)
print("------")
np.vsplit(a,3)# vsplit函數是縱向切割,傳入兩個參數,第一個參數是要被切割的矩陣,第二個是切成幾份。也可以做指定位置切割:
代碼輸出:
[[2. 7. 2. 9. 8. 6. 5. 4. 9. 9. 6. 5.]
[3. 6. 3. 3. 6. 8. 0. 7. 6. 5. 0. 1.]]
------
[array([[2., 7., 2., 9.],
[3., 6., 3., 3.]]), array([[8., 6., 5., 4.],
[6., 8., 0., 7.]]), array([[9., 9., 6., 5.],
[6., 5., 0., 1.]])]
------
[array([[2., 7., 2.],
[3., 6., 3.]]), array([[9.],
[3.]]), array([[8., 6., 5., 4., 9., 9., 6., 5.],
[6., 8., 0., 7., 6., 5., 0., 1.]])]
-----分割線----
[[5. 4.]
[0. 1.]
[8. 2.]
[7. 0.]
[4. 4.]
[5. 0.]
[9. 7.]
[7. 1.]
[8. 4.]
[5. 8.]
[4. 3.]
[8. 4.]]
------
[array([[5., 4.],
[0., 1.],
[8., 2.],
[7., 0.]]), array([[4., 4.],
[5., 0.],
[9., 7.],
[7., 1.]]), array([[8., 4.],
[5., 8.],
[4., 3.],
[8., 4.]])]
關于矩陣複制
指派符号
指向一樣,資料共享,記憶體空間是一塊,類似一個人有兩個名字,這不是真的複制。
a = np.arange(12)#建立一個12個元素的向量,命名為a
b = a
print(b is a)#列印判斷b是不是a的結果
b.shape = (3,4)#把一維向量b的形狀轉化成3行4列的而二維矩陣
print (a.shape)#列印a的形狀
print (id(a))#列印a的id,id是某個變量在記憶體中生成時,被賦予的具有唯一性的記憶體辨別
print (id(b))#列印b的id
列印輸出:
True
(3, 4)
4834999312
4834999312
淺複制
指向不同,但資料共享。
c = a.view()# 矩陣的view方法是淺複制,即c和a指向不同,但又同時共享着資料
print(c is a)#列印c是不是a的結果
c.shape = (2,6)
print (a.shape)
c[0,4] = 1234#把矩陣c第1行第5列元素指派為1234
print (a)
output:
False
(3, 4)
[[ 0 1 2 3]
[1234 5 6 7]
[ 8 9 10 11]]
由此得出,矩陣的view方法是淺複制,即c和a指向不同,但又同時共享着資料。
深複制
想要完全
d = a.copy() # 矩陣的copy方法是深複制,即d和a指向不同,資料不同
print(d is a)
d[0,0] = 9999
print(d)
print(a)
output:
False
[[9999 1 2 3]
[1234 5 6 7]
[ 8 9 10 11]]
[[ 0 1 2 3]
[1234 5 6 7]
[ 8 9 10 11]]
排序和索引
最值
data = np.sin(np.arange(20)).reshape(5,4) #随機建立一個矩陣
print(data)
print("----")
ind = data.argmax(axis=0)#矩陣的argmax方法是求每列或每行的最大值,axis=0這個參數指按列統計(結果是該列的第幾行最大,友善後面拿出來),axis=1是按行統計。
print(ind)
print("----")
print(data.shape)
print(data.shape[1]) #取出來具體的列的數目
print(data.shape[0]) #取出來具體的行的數目
print("----")
data_max = data[ind, range(data.shape[1])]#把每列最大的元素取出來。 2行0列,0行1列,3行2列,1行3列
print(data_max)
range() 函數可建立一個整數清單,一般用在 for 循環中。
data.shape[1] 是列數 data.shape[0] 是行數
關于np.sin(array),是獲得矩陣裡元素的正弦值。相關的資料可以檢視:https://www.runoob.com/numpy/numpy-mathematical-functions.html
擴充
a = np.arange(0, 40, 10) #随機建立一個矩陣,從0到40,step為10,周遊出0-10-20-30
print(a)
print("---")
b = np.tile(a, (3, 5)) # tile方法是矩陣拓展方法,第一參數是把a作為整體當做一個元素進行擴充,第二個參數是擴充成3行5列的矩陣。
print(b)
輸出的結果:
[ 0 10 20 30]
---
[[ 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30]
[ 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30]
[ 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30]]
排序
a = np.array([[4, 3, 5], [1, 2, 1]])
print(a)
print("----")
b = np.sort(a, axis=1)#按照行對矩陣a排序,預設是從小到大排序,把新矩陣指派給b
print(b)
print("----")
a.sort(axis=1)# 這種調用方法和np.sort(a,axis=1)效果一樣
a = np.array([4, 3, 1, 2])
j = np.argsort(a)# argsort方法是先對矩陣a排序,然後對應求出每個元素在原來矩陣a中的索引
print (j)
print (a[j]) #把這個索引傳入原矩陣就可以得到排序後的新矩陣。
output:
[[4 3 5]
[1 2 1]]
----
[[3 4 5]
[1 1 2]]
----
[2 3 1 0]
[1 2 3 4]