天天看點

2.python包-numpy總結01

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矩陣轉置,即把原來的第一列變為新矩陣的第一行,第二列變為新矩陣的第二行,即原來的行變為列,原來的列變為行,依次類推。      

代碼的輸出為:

2.python包-numpy總結01

reshape重置矩陣的形狀

print("----")
#reshape(3,-1)方法是修改矩陣的形狀,3是3行,-1這個數表示讓計算機根據其他次元的資料.
#自動算出-1這個地方應該填寫多少,并完成修改。矩陣的拼接:
print(a.reshape(3,-1))      

代碼的輸出:

2.python包-numpy總結01

矩陣的橫向縱向拼接

主要是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]      

總結

參考資料