python列表和Numpy數組的區別
python列表和Numpy數組的區別
1二者都可以用於處理多維數組。
Numpy中的ndarray對象用於處理多維數組,它作為一個快速而靈活的大數據容器。Python列表可以存儲一維數組,通過列表的嵌套可以實現多維數組。
2存儲效率和輸入輸出性能不同。
Numpy專門針對數組的操作和運算進行了設計,存儲效率和輸入輸出性能遠優於Python中的嵌套列表,數組越大,Numpy的優勢就越明顯。
3元素數據類型。
通常,Numpy數組中的所有元素的類型都必須相同的,而Python列表中的元素類型是任意的,所以在通用性能方面Numpy數組不及Python列表,但在科學計算中,可以省掉很多循環語句,代碼使用方面比Python列表簡單的多。
array的創建:
Numpy數組創建時,參數既可以是list,也可以是元組。例如:
a=np.array((1,2,3))
#參數是tuple
b=np.array([6,7,8])
#參數是list
c=np.array([[1,2],[3,4,]])
#參數是二維list
除此之外,還可以使用numpy提供的其他方法創建一個數組,例如:
arr1=np.arange(1,10,1)
arr2=np.linspace(1,10,10)
np.arange(a,b,c)表示產生從a-b不包括b,間隔為c的一個array,數據類型默認是int32。但是linspace(a,b,c)表示的是把a-b平均分成c分,它包括b。
今天讀程序關於步長的運用:
['%x' %int(''.join(avg_list[x:x+4]),2) for x in range(0,32*32,4)]
這個是感知哈希算法的一個步驟,將二進制數據改寫為十六進制,以便於下一步的判斷。這裡我的一個二進制數據的長度是32×32,且二進制轉十六進制可以每隔4位來轉,所以就可以將步長設置為4.
從函數規則創建數組也非常方便,numpy的fromfunction函數可以實現這個功能:
def f(x,y):
... return 10*x+y
... b=np.fromfunction(f,(2,2))
該函數的具體內容如下:
元素訪問:
array的一維數組的訪問方式:
定義一個一維數組,arr=np.array([0,1,2,3,4,5,6,7,8,9])
其中,arr[a:b:n]表示按步長為n取從a到b的元素,當n為-1的時候,從右向左訪問。
array的二維數組的訪問方式:
對於二維數組arr=np.array([[1,2,3],[4,5,6]]),我們可以通過一下的方式訪問:
以上的語句都返回了二維數組的第一行,但是凡是通過“:”訪問的,最終都在外面加了“[ ]”,可以像第2語句那樣,再用一個索引得到最終的結果。
這裡,我想起來最近截取圖片的一個例子。
通常,我們用imread的圖片就保存在一個數組對象中,例如:img=[[0,1,2], [3,4,5],[6,7,8]].現在我想截取這個圖片的(0,0)到(1,1)矩形區域,可以通過下面的語句完成:img[0:1,0:1].截取下的結果就是[[0,1],[3,4]].
另外,還有一個需要注意的點:array的索引最終產生的是一個「 原始數據的淺拷貝」,他和原始數據共用一塊內存。
>>> import numpy as np
>>> a=np.array([0,1,2])
>>> b=a[:2]
>>> b
array([0, 1])
>>> b[0]=100
>>> b
array([100, 1])
>>> a
array([100, 1, 2])
當我們修改了b的第一個元素的時候,a的第一個元素也被修改了。因為他們都是指向的同一個內存。
這是因為當我們執行b=a[:2]等語句的時候,拷貝的是指向這個元素的指針,當我們想要修改的時候,也是修改了指針指向的元素值。
>>> a=[0,1,2]
>>> b=a[:2]
>>> b
[0, 1]
>>> b[0]=100
>>> b
[100, 1]
>>> a
[0, 1, 2]
與之不同的是,list對象在執行的時候拷貝了數據與指針,就不會有這種狀況啦。
除了上面介紹的這種根據索引訪問元素的方法,array還有自己更為優秀的方法!
1使用布爾數組
>>> a=np.array([0,1,2,3,4,5,6])
>>> b=a>3
>>> b
array([False, False, False, False, True, True, True])
>>> a[b]
array([4, 5, 6])
值得注意的是,這種方法只適用於數組,list沒有資格。如上例所示,布爾索引最終返回的是下標為True的數據。
2列表索引
>>> a=np.array(['a','b','c','d','e'])
>>> a
array(['a', 'b', 'c', 'd', 'e'], dtype='<U1')
>>> b=[0,1]
>>> a[b]
array(['a', 'b'], dtype='<U1')
>>>
列表索引適用於數組和list對象。
以上兩個「花式索引」他們都不和原來的數據共享內存。
總結
今天這篇筆記主要是想要總結一下array和list的區別。
一個python元素其實是一個指向這個包含所有python object信息的內存的位置指針。
list:一個指向一系列指針塊的指針,其中每個指針都指向一個完整的python object-對象,例如integer。每一個list 元素是一個包括數據和信息類型的完整結構。所以列表可以填充任意類型的數據。
numpy.array:底層是C語言。有步長strides,dimensions,data三屬性。他的元素類型固定,缺乏靈活,但是更方便進行存儲和處理數據。
這篇筆記的pdf可以通過擴展獲取,提取碼: xy3r 。