原文地址: http://blog.csdn.net/liyaohhh/article/details/51055147#reply
python中的list是python的內置數據類型,list中的數據類不必相同的,而array的中的類型必須全部相同。在list中的數據類型保存的是數據的存放的地址,簡單的說就是指針,並非數據,這樣保存一個list就太麻煩了,例如list1=[1,2,3,'a']需要4個指針和四個數據,增加了存儲和消耗cpu。
numpy中封裝的array有很強大的功能,里面存放的都是相同的數據類型
- list1=[1,2,3,'a']
- print list1
- a=np.array([1,2,3,4,5])
- b=np.array([[1,2,3],[4,5,6]])
- c=list(a) # array到list的轉換
- print a,np.shape(a)
- print b,np.shape(b)
- print c,np.shape(c)
運行結果:
- [1, 2, 3, 'a'] # 元素數據類型不同,並且用逗號隔開
- [1 2 3 4 5] (5L,) # 一維數組,類型用tuple表示
- [[1 2 3]
- [4 5 6]] (2L, 3L)
- [1, 2, 3, 4, 5] (5L,)
創建:
array的創建:參數既可以是list,也可以是元組.使用對應的屬性shape直接得到形狀
- a=np.array((1,2,3,4,5))# 參數是元組
- b=np.array([6,7,8,9,0])# 參數是list
- c=np.array([[1,2,3],[4,5,6]])# 參數二維數組
- print a,b,
- c.shape()
也可以直接改變屬性array的形狀,-1代表的是自己推算。這里並不是T, reshape(())也可以
- c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])
- c.shape # (3L, 4L)
- c.shape=4,-1 //c.reshape((2,-1))
- c
- <pre style="box-sizing: border-box; overflow: auto; font-size: 14px; padding: 0px; margin-top: 0px; margin-bottom: 0px; line-height: 17.0001px; word-break: break-all; word-wrap: break-word; border: 0px; border-radius: 0px; white-space: pre-wrap; vertical-align: baseline; background-color: rgb(255, 255, 255);">array([[ 1, 2, 3],
- [ 4, 4, 5],
- [ 6, 7, 7],
- [ 8, 9, 10]])
這里的reshape最終相當於是一個淺拷貝,也就是說還是和原來的書c使用相同的內存空間
- d=c.reshape((2,-1))
- d[1:2]=100
- c
array([[ 1, 2, 3], [ 4, 4, 5], [100, 100, 100], [100, 100, 100]])
前面在創建數組的時候並沒有使用數據類型,這里我們也可以使用數據類型。默認的是int32.
- a1=np.array([[1,2,3],[4,5,6]],dtype=np.float64)
- print a1.dtype,a.dtype #float64 int32<pre style="margin-top: 0px; margin-bottom: 0px; line-height: 17.0001px; box-sizing: border-box; overflow: auto; font-size: 14px; padding: 0px; word-break: break-all; word-wrap: break-word; border: 0px; border-radius: 0px; white-space: pre-wrap; vertical-align: baseline; rgb(255, 255, 255);">
- arr1=np.arange(1,10,1) #
- arr2=np.linspace(1,10,10)
- print arr1,arr1.dtype
- print arr2,arr2.dtype
[1 2 3 4 5 6 7 8 9] int32 [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] float64
np.arange(a,b,c)表示產生從a-b不包括b,間隔為c的一個array,數據類型默認是int32。但是linspace(a,b,c)表示的是把a-b平均分成c分,它包括b。
有時候我們需要對於每一個元素的坐標進行賦予不同的數值,可以使用fromfunction函數
- def fun(i):
- return i%4+2
- np.fromfunction(fun,(10,))
array([ 2., 3., 4., 5., 2., 3., 4., 5., 2., 3.])
fromfunction必須支持多維數組,所以他的第二個參數必須是一個tuple,只能是(10,),(10)是錯誤的。
- def fun2(i,j):
- return (i+1)*(j+1)
- np.fromfunction(fun2,(9,9))
array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9.], [ 2., 4., 6., 8., 10., 12., 14., 16., 18.], [ 3., 6., 9., 12., 15., 18., 21., 24., 27.], [ 4., 8., 12., 16., 20., 24., 28., 32., 36.], [ 5., 10., 15., 20., 25., 30., 35., 40., 45.], [ 6., 12., 18., 24., 30., 36., 42., 48., 54.], [ 7., 14., 21., 28., 35., 42., 49., 56., 63.], [ 8., 16., 24., 32., 40., 48., 56., 64., 72.], [ 9., 18., 27., 36., 45., 54., 63., 72., 81.]])
雖然說,這里提供了很多的直接產生array的方式,但是大部分情況我們都是會從list進行轉換,因為在實際的處理中,我們需要從txt加載文件,那樣直接讀入的數據顯示存放到list中,需要處理的時候我們轉換到array,因為
array的設計更加符合我們的使用,涉及到矩陣的運算在使用mat,那么list主要就是用進行元素的索取。
- def loaddataSet(fileName):
- file=open(fileName)
- dataMat=[] //
- for line in file.readlines():
- curLine=line.strip().split('\t')
- floatLine=map(float,curLine)//這里使用的是map函數直接把數據轉化成為float類型
- dataMat.append(floatLine)
- return dataMat
上面的韓順返回最終的數據就是最初的list數據集,再根據不同的處理需求是轉化到array還是mat。其實array是mat的父類,能用mat的地方,array理論上都能傳入。
元素訪問:
- arr[5] #5
- arr[3:5] #array([3, 4])
- arr[:5] #array([0, 1, 2, 3, 4])
- arr[:-1]# array([0, 1, 2, 3, 4, 5, 6, 7, 8])
- arr[:] #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
- arr[2:4]=100 # array([ 0, 1, 100, 100, 4, 5, 6, 7, 8, 9])
- arr[1:-1:2] #array([ 1, 100, 5, 7]) 2 是間隔
- arr[::-1] #array([ 9, 8, 7, 6, 5, 4, 100, 100, 1, 0])
- arr[5:2:-1]# -1的間隔表示從右向左所以5>2 #array([ 5, 4, 100])
上面是array的一維數組的訪問方式,我們再來看看二維的處理方式
- print c[1:2]# c[1:2].shape-->(1L, 3L)
- print c[1:2][0] # shape-->(3L,)
[[4 4 5]] [4 4 5]
- print c[1]
- print c[1:2]
[4 4 5] [[4 4 5]]
- print c[1][2]
- print c[1:4]
- print c[1:4][0][2]
5 [[ 4 4 5] [100 100 100] [100 100 100]] 5
可以看出對於有:的表達最終的結果外面還嵌套一層list的[],。訪問的一定要注意,python最bug的就是,語法
靈活,不管怎樣寫索引語法都是正確的,但是最終的書結果卻讓你大跌眼鏡。
還有array的索引最終產生的是一個一個原始數據的淺拷貝,還和原來的數據共用一塊兒內存
- b=arr[1:6]
- b[:3]=0
- arr #<pre style="box-sizing: border-box; overflow: auto; font-size: 14px; padding: 0px; margin-top: 0px; margin-bottom: 0px; line-height: 17.0001px; word-break: break-all; word-wrap: break-word; border: 0px; border-radius: 0px; white-space: pre-wrap; vertical-align: baseline; rgb(255, 255, 255);">array([0, 0, 0, 0, 4, 5, 6, 7, 8, 9])
產生上面的原因是因為array中直接存放的數據,拷貝的話直接拿走的是pointer,沒有取走數據,但是list卻會直接發生深拷貝,數據指針全部帶走
- list1=list(c)
- list1[1]=0
- list1 #上面修改的0並沒有被改變
[array([1, 2, 3]), 0, array([100, 100, 100]), array([100, 100, 100])]
除了這些之外還有自己的更加牛掰的方式(只能用array)
1)使用布爾數組.感覺甚是強大,就不要自己寫什么判斷語句啦,注意這種方式得到結果不和原始數組共享空間。布爾索引僅僅適用於數組array,list沒資格用。布爾索引最終得到下標索引為true的數據。索引只能是布爾數組
- a=np.array(a*2)
- a>5
- a[a>5] #
array([16, 32, 48, 64, 80, 16, 32, 48, 64, 80])
2)列表索引
列表索引可以是數組和list。返回的數據不和原來的數據共享內存。索引可以是list和array
- x=np.arange(10)
- index=[1,2,3,4,5]
- arr_index=np.array(index)
- print x
- print x[index] # list索引
- print x[arr_index] # array索引
[0 1 2 3 4 5 6 7 8 9] [1 2 3 4 5] [1 2 3 4 5]
array和list區別*2
- a=np.arange(10)
- lista=list(a)
- print a*2
- print lista*2
[ 0 2 4 6 8 10 12 14 16 18] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
array的廣播
- a = np.arange(0, 60, 10).reshape(-1, 1)
- b = np.arange(0, 5)
- print a
- print b
[[ 0] [10] [20] [30] [40] [50]] [0 1 2 3 4]
- print np.add(a,b,c)
[[ 0 1 2 3 4] [10 11 12 13 14] [20 21 22 23 24] [30 31 32 33 34] [40 41 42 43 44] [50 51 52 53 54]]