python常用序列list、tuples及矩陣庫numpy的使用


 

 

近期開始學習python機器學習的相關知識,為了使后續學習中避免編程遇到的基礎問題,對python數組以及矩陣庫numpy的使用進行總結,以此來加深和鞏固自己以前所學的知識。

Section One:Python數組的使用

在python中,數組這個概念其實已經被淡化了,取之的是元組和列表,下面就列表和元組進行相關的總結和使用。

  Subsection One: List

  list列表本質是一種序列類型的數據結構,有點類似於C/C++中所學的數組,但又不同。他們的相同之處在於,二者中的每個元素都分配有一個索引值來進行訪問,如:

1 #python list
2 list1 = ['physics', 'chemistry', 1997, 2000]
3 print(list1[0])
View Code

而在C/C++中我們知道,數組也可以通過這種數組名加索引值的方式來訪問,在此不做贅述。

但是,細心的話,我們會發現,python中的列表與C/C++中有所不同,它可以包含不同的數據類型,而C/C++中則不可以。此外,在上面的代碼中,我們可以看到,二者有着相同的創建方式。

但在python中,對於list列表類型的訪問,有着不同的方式,下面就列表的訪問進行總結:

 1 """List:
 2 --------------------------------
 3 """
 4 # create a list
 5 list1 = ['physics', 'chemistry', 1997, 2000]
 6 
 7 # two methods to access a list as follows:
 8 print "list1[0]", list1[0] 
 9 print "list1[1:4]", list1[1:4]
10 
11 print "list1[-1]", list1[-1]
12 print "list1[-2]", list1[-2]
13 
14 print "list1[1:]", list1[1:]
View Code

 

從上面兩種方式,其實可以看到,python中的列表可以通過"起始索引:終止索引(可選)"的方式,來直接訪問列表中的一串數據,這在C/C++中是無法做到的,這給我們帶來極大的便利性,加上終止索引,表示訪問從起始索引到終止索引之間的全部數據,不加則意味着要訪問從起始索引到該列表末尾的全部數據。

此外,在列表中,索引值為負代表着從列表末尾來訪問這個列表,圖上圖三、四例子可以看到。

此外,python中對於列表,引入了以下幾種方法來更新和刪除列表,並賦予幾種訪問列表屬性的方法。

# update and delete 
list1.append('Google')
print list1

列表可以通過append方法,往列表的末尾添加新的元素,在list1列表的基礎上,這里添加了一個叫做google的字符串元素。

del list1[2]
print "after deleting value at index 2", list1
View Code

可以看到,使用del函數將索引為2的數據刪除了,此外,del函數還能結合之前提到的訪問數組的方式來刪除相關元素,如:

del list1[1:]
print "after deleting value by list1[1:]", list1
View Code

同理,采用起始index:終止index的方式,也是能夠實現刪除列表中一段數據的。

此外,python中提供了一個len函數,來獲取一個列表的長度,使用"+"操作符能夠實現不同數組之間的合並,使用"*"操作符實現創建包含n個相同元素的列表,以及一些循環和遍歷方式來確定數據是否在列表中,下面給出相關的操作:

"""List:
--------------------------------
"""
# create a list
list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3 , 4]

l = len(list1)
print "access len function to get the length of list1"
print l

# + operator
print list1 + list2

list3 = list1 + list2

print "list3:", list3

# * operator
list4 = ['hhhh'] * 4
print list4

#traverse
print "traverse list1:"
for x in list1:
    print x

#confirm x in list
print "confirm x in list"
print 2 in list1
print 1997 in list1
View Code

此外,還可以通過min和max函數來獲取列表的最大最小值,count函數用以計算某元素在列表中的出現次數,remove來移除匹配到的數據,sort函數進行排序,reverse函數進行逆序,這些可以在list的官方文檔中查詢到。

  Subsection Two: 元組

  元組的創建根列表的很類似,但是它用括號進行創建:

"""
Tuples
------------------------------
"""

tup1 = (1, 2, 3, "Google")
print tup1

tup2 = ('flesh',)
print tup2
View Code

細心的小伙伴們可能會看到,我在創建第二個tuples的時候,里面雖然只有一個元素,但是,我還是用了一個逗號,其實,這是很有必要的,雖然不加也不會有編譯錯誤,在這部分代碼中。但是,在其他情況則不一定了,比如,我們使用元組作為返回參數,如果不加逗號,但是返回的元組中只有一個數據,比如26,那么,計算機就會因為無法識別該元素是數字26還是元組26。因此,加上是必要的,也有助於我們養成良好的編程習慣。

元組的訪問呢與列表是一樣的,因為它們倆都是python中最為常見的序列結構,在這里不做贅述,有興趣的小伙伴可以自己去嘗試一下下,值得注意的是,訪問時的形式與列表的相同,不是L(index)的方式,而是L[index]。

此外,在元組中,對相關數據的修改是非法的,如下所示:

print "modify the data at index 2"
tup1[2] = 100
print tup1
View Code

所以給位小伙伴們在使用元組時一定要注意呀!

但是元組中,可以使用"+"以及"*"兩個操作符來進行對元組的修改。

其余的相關方法如len等,而這類似,可以通過查閱文檔來了解。

Section Two: Numpy庫的使用(后續補充,要吃飯了23333)

補充:

Numpy是python中的矩陣庫,可以方便的讓我們學習。

可以使用cmd命令行來安裝該庫,命令如下:

pip install Numpy
View Code

安裝完成后,即可使用。python提供了一個pydoc命令,可以用於查看本地所安裝的python庫,也是在cmd命令行中輸入。

python -m pydoc -p 1234

-p指定啟動的服務的端口號,可以隨意指定不沖突的端口號

-m則是py中的一種工作模式了

1234就是-p下指定的一個端口號。運行后cmd會出現這樣的結果:

然后根據所給的url直接在瀏覽器中輸入,就可以訪問到本地的庫文檔,個人比較喜歡直接查文檔的方式進行學習。

該界面中包含numpy庫下轄的多個類以及各個類中所包含的函數模塊,並在每個接口部分,給出了相應的使用案例。

下面給出numpy的使用:

numpy的調用,與其他庫文件的調用一樣,采用import方式進行調用:

import numpy as np

通過這種方式,可以將本地的numpy庫,導入當前的py文件中進行使用。此外,numpy給python的學習者以極大的便利來使用矩陣,尤其是其所提供的help函數,能夠在使用者不知道或者忘記怎么使用其內部函數的時候,給予幫助。

調用方式如下:

help(function name)

在這里我以下面這個例子為例:

1 """
2 Numpy Learning
3 ------------------------------------------------------
4 """
5 
6 import numpy as np
7 
8 help(np.sort)
View Code

sort函數是numpy中自帶的一個排序函數,當運行help方法進行獲取他的使用后,就可以在console框中得到相應的調用案例:

這種方式能夠在一定程度上提高我們查詢文檔的速度。

對於矩陣的使用,可以自行生成,也可以借助numpy中所帶的相關類進行獲取,如Datasource,該類可以通過如下方式導入進行使用

from numpy import DataSource

導入后,就可以直接進行調用,以鳶尾花數據庫中的數據為例:

實例化DataSource對象以后,該對象包含相對應的方法,可以在上文中提到的本地庫函數界面中查詢到,典型的就有exists方法,用以判斷訪問的數據是否存在。

 1 """
 2 Numpy Learning
 3 ------------------------------------------------------
 4 """
 5 
 6 import numpy as np
 7 from numpy import DataSource
 8 
 9 # method to get data
10 url_name = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
11 repos = DataSource()
12 print repos.exists(url_name)
View Code

運行后輸出為True,說明存在,我們可以直接通過url_name來訪問相應的數據。

 1 """
 2 Numpy Learning
 3 ------------------------------------------------------
 4 """
 5 
 6 import numpy as np
 7 from numpy import DataSource
 8 
 9 # method to get data
10 # url name to access
11 url_name = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
12 ds = DataSource()
13 dataset = ds.open(url_name, mode='r')
14 
15 for key in dataset:
16     print key
View Code

數據的訪問這里選擇只讀形式,然后通過for循環對獲取的數據進行解析輸出:

這種方式獲取的數據存在一定的局限性,因為每個key其實是一個list對象,其中數據全部為字符串型數據。進一步的使用則需要對數據進行解析,可以簡單的通過pandas數據庫來獲取整理數據,這個庫是python中的一個數據分析庫,事倍功半,pandas的使用,將會在后續另一篇blog中進行敘述。本文采用一些線性代數中的簡單實例,來使用numpy矩陣庫。

 ex1:求解下列線性方程:

通常,線性方程可以表示成Ax = b的形式,A即為線性方程組的系數矩陣,b即為右側的值構成的列向量。則可以通過在方程兩邊同乘以系數矩陣的逆矩陣來求得x的解。在這里給出我手解得到的值x1=1;x2=x3=0。

下面借助numpy進行求解,代碼如下:

 1 #coding:utf-8
 2 """
 3 Numpy Learning
 4 ------------------------------------------------------
 5 """
 6 
 7 import numpy as np
 8 import numpy.linalg as lg
 9 
10 # create an matrix
11 """
12 np.array(parameter matrix)
13 the matrix can be one-dimensional or multi-dimensional
14 It's worth noting that if matrix is one-dimensional, the fellow method 
15 can be used:
16     np.array([1,2,3,4])
17 else like the given sample
18 """
19 # A = np.array([1, 2, 3, 4])
20 # print "onr-dimensional matrix: "
21 # print A
22 # A = np.array([1, 2, 3, 4])
23 A = np.array([[1, 2, 3], [2, 2, 5], [3, 5, 1]])
24 b = np.array([[1], [2], [3]])
25 
26 A_inv = lg.inv(A)
27 
28 # x = np.dot(A_inv, b)
29 x = A_inv.dot(b)
30 print "x is calculated by dot function:"
31 print x
32 # print "x is calculated by * operation: "
33 # print A_inv * b
34 
35 print("The inverse of A is :")
36 print A_inv
37 print("Column vector b is :")
38 print b
39 print("The result of A_inv * b is :")
40 print A_inv * b
41 
42 print "The examples of * operator :"
43 a = np.array([[1, 2, 3], [2, 2, 5], [3, 5, 1]])
44 b = np.array([[1], [2], [3]])
45 print a * b
46 
47 # error
48 # a = np.array([[1, 2, 3], [2, 2, 5], [3, 5, 1]])
49 # b = np.array([[1], [2]])
50 # print a * b
51 
52 # error
53 # a = np.array([[1, 2, 3], [2, 2, 5], [3, 5, 1]])
54 # b = np.array([[1, 2], [2, 2], [3, 2]])
55 # print a * b
View Code

代碼中給出了使用numpy創建矩陣的兩種方式,一種是創建多維矩陣另一種則是創建一維的矩陣,即行向量。可以看到,當創建行向量的時候,只需要傳入一個list類型的對象即可,而創建多維矩陣的時候,需要以行向量作為一個list的元素構成一含有多個子list的一個list作為參數傳遞進去,以此來創建矩陣。

在這里用到了numpy底下linalg中的一個方法即inv方法,用於求矩陣的逆矩陣。需要注意的是,numpy中,對" * "、" / "、" - "、" + "進行了重載,以此來滿足矩陣的運算需要,但是,在這些運算符中," * "運算符不同於其他工具中的功能,它實現的不是矩陣的點乘,而是對矩陣的元素進行操作,即,當兩個矩陣a、b的行相同,且當矩陣a或b的列滿足矩陣a的列數等於矩陣b的列數,或者矩陣a或者b的列數等於1時,兩個矩陣中的元素進行操作,上述代碼的運行結果可以很直觀的看到這一點。

上述代碼的運行結果如下所示:

從上述代碼可以看到,矩陣的點乘是每個numpy矩陣對象自帶的方法,可以通過np.dot(parameter A, parameter B)的方式,也可以直接A.dot(B)。而求逆運算則包含在linalg模塊中。

此外,在每個numpy對象中包含以下幾種屬性:ndim、shape、size、dtype、itemsize以及data,下面以ex1線性方程組的系數矩陣A為例來輸出這些屬性。

 1 A = np.array([[1, 2, 3], [2, 2, 5], [3, 5, 1]])
 2 print "The metrix A"
 3 print A
 4 print "A.ndim: "
 5 print A.ndim
 6 print "A.shape: "
 7 print A.shape
 8 print "A.size: "
 9 print A.size
10 print "A.dtype: "
11 print A.dtype
12 print "A.itemsize"
13 print A.itemsize
14 print "A.data"
15 print A.data
View Code

運行上述代碼可以得到如下結果:

從上述結果可知,indim屬性表征的是一個矩陣的維度,即一個矩陣中的元素最多能用多少個矩陣下標來表示,在這里,由於是二維矩陣,因此,該值為2。如果是三維矩陣,那么一個元素需要3個索引值來表示,那么indim屬性值也就為3。shape屬性表示的是n*m矩陣的尺寸,在這里是個3*3矩陣,因此該值為(3, 3),則該值的長度即為indim值。size表示的是這個矩陣中包含的元素的個數,該屬性與shape屬性有着相同的表征含義。dtype則表示的是矩陣中元素的數據類型。itemsize則表示的是一個元素的字節數,在這里由於是32位整型,因此,該值為32/8 = 4。data屬性表示的是矩陣所對應的緩存中的實際數據,一般來說是用不到這個屬性的。

 除了以上內容,我們在學習線性代數的過程中,通常會遇到一些計算的小技巧,比如借助單位矩陣來求一些矩陣等,下面還是以線代中的一些例子為例。

ex2:

上題中需要用到一個單位矩陣E,在numpy中,提供了相應的方法來生成一定要求的矩陣,下面結合例子來調用輸出這些方法。

首先,給出numpy中自帶的一些創建特殊矩陣的方法:

 1 # Create an array full of zeros, the type of parameter likes np.shape.
 2 Zero = np.zeros((3, 3))
 3 print "Zero array: "
 4 print Zero
 5 
 6 # The function ones creates an array full of ones
 7 ones = np.ones((4, 4))
 8 print "Ones array: "
 9 print ones
10 
11 # The function empty creates an array whose initial content is
12 # random and depends on the state of the memory. By default, 
13 # the dtype of the created array is float64.
14 
15 Empty = np.empty((3, 3))
16 print "Empty array: "
17 print Empty
18 
19 # To creates sequences of numbers, this function
20 # analogous to range  that returns arrays instead of lists.
21 Sequences = np.arange(10, 30, 2)
22 print "Sequences array: "
23 print Sequences
24 
25 # The function creates a sequences array by predicting the 
26 # number of elements obtained.
27 Linspace = np.linspace(10, 30, 25)
28 print "Linspace array: "
29 print Linspace
30 
31 # The function creates a N-th order identity matrix.
32 E = np.eye(4)
33 print "E array: "
34 print E
View Code

運行以上代碼可以得到如下輸出結果:

從上圖可以看到:

  • np.zeros(parameter A)的方式,可以創建一個n*m型的零矩陣。這個A類似之前輸出的屬性shape,一個元組形式的參數,當然,n*m只是舉例說明,實際可以是多維的,如(i, j, k)。
  • np.ones(parameter A)與zeros()函數相同,所傳參數也是一個元組類型數據,只是結果有所不同,生成的是一個全1的矩陣。
  • np.empty(parameter A)創建的是一個隨機數矩陣,所傳參數與zeros和ones相同,只是生成的結果是一個隨機數構成的矩陣,內部元素的數據與內存有關,數據類型默認是64位浮點型。
  • np.arange(parameter A)創建的是一個等差序列list,參數A是一個包含三個數據的元組,(a,b,c),[a,b)為這個arange的范圍,左閉右開區間,即不包括b的,步長為c的一個序列。
  • np.linspace(parameter A)則是創建一個等差序列list,與arange不同的是,這里參數A依舊是(a, b, c),但是,這個元組中的c變量表示的不是步長,而是從a到b這個左開右閉區間內,所包含的數的個數。
  • np.eye(parameter A)創建的一個N階的單位矩陣,參數A為一個整型數據,表示的是單位矩陣的階數。

此外,numpy中創建的矩陣也是可以對其進行python中的切片和迭代操作的。

結合以上的內容,可以非常方便的創建一個單位矩陣E,進而求解所給出的那道題。代碼如下所示:

1 A = np.array([[1, 0, 0, 0], [-2, 3, 0, 0],
2              [0, -4, 5, 0], [0, 0, -6, 7]])
3 
4 E = np.eye(4)
5 
6 C = lg.inv((E + A))
7 B = C.dot((E - A))
8 E_add_B_inv = lg.inv((E + B))
9 print E_add_B_inv
View Code

運行上述代碼,即可求得:

可以看到,所求結果與手算結果相一致,第四行第二列的那個數值直接視為0。

補充:

在numpy中,每個np對象還包含轉置操作:

1 A = np.array([[1, 0, 0, 0], [-2, 3, 0, 0],
2              [0, -4, 5, 0], [0, 0, -6, 7]])
3 print "The transposition of A: "
4 print A.T
View Code

得到結果如下所示:

 

以上是目前的我本人所需要用到的一些numpy的知識點,后續隨着學習的深入會繼續補充該文。還有更多的內容,中文版的入門教程可以參考這篇博客https://www.cnblogs.com/qflyue/p/8244331.html

英文版的可以直接查官方的文檔了

https://docs.scipy.org/doc/numpy-dev/user/quickstart.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM