python中的list和array的不同之處


  

原文地址:  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有很強大的功能,里面存放的都是相同的數據類型

 

[python]  view plain  copy
 
  1. list1=[1,2,3,'a']  
  2. print list1  
  3.   
  4. a=np.array([1,2,3,4,5])  
  5. b=np.array([[1,2,3],[4,5,6]])  
  6. c=list(a)   # array到list的轉換  
  7. print a,np.shape(a)  
  8. print b,np.shape(b)  
  9. print c,np.shape(c)  

運行結果:

 

[python]  view plain  copy
 
  1. [1, 2, 3, 'a'] # 元素數據類型不同,並且用逗號隔開  
  2. [5] (5L,) # 一維數組,類型用tuple表示  
  3. [[3]  
  4.  [6]] (2L, 3L)  
  5. [1, 2, 3, 4, 5] (5L,)  

 

 

創建:

    array的創建:參數既可以是list,也可以是元組.使用對應的屬性shape直接得到形狀
[python]  view plain  copy
 
  1. a=np.array((1,2,3,4,5))# 參數是元組  
  2. b=np.array([6,7,8,9,0])# 參數是list  
  3. c=np.array([[1,2,3],[4,5,6]])# 參數二維數組  
  4. print a,b,  
  5. c.shape()  

   也可以直接改變屬性array的形狀,-1代表的是自己推算。這里並不是T, reshape(())也可以
[python]  view plain  copy
 
  1. c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])  
  2. c.shape # (3L, 4L)  
  3. c.shape=4,-1   //c.reshape((2,-1))  
  4. c    
[python]  view plain  copy
 
  1. <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],  
  2.        [ 4,  4,  5],  
  3.        [ 6,  7,  7],  
  4.        [ 8,  9, 10]])  
   
   這里的reshape最終相當於是一個淺拷貝,也就是說還是和原來的書c使用相同的內存空間
 
         
[python]  view plain  copy
 
  1. d=c.reshape((2,-1))  
  2. d[1:2]=100  
  3. c  

array([[  1,   2,   3],
       [  4,   4,   5],
       [100, 100, 100],
       [100, 100, 100]])

   前面在創建數組的時候並沒有使用數據類型,這里我們也可以使用數據類型。默認的是int32.
 
         
[python]  view plain  copy
 
  1. a1=np.array([[1,2,3],[4,5,6]],dtype=np.float64)  
  2. 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);">  
 
         前面在創建的時候我們都是使用的np.array()方法從tuple或者list轉換成為array,感覺很是費勁,numpy自己提供了很多的方法讓我們自己直接創建一個array. 
         
 
         
 
 
         
[python]  view plain  copy
 
  1. arr1=np.arange(1,10,1) #   
  2. arr2=np.linspace(1,10,10)  
  3. print arr1,arr1.dtype  
  4. 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函數
 
         
 
         
[python]  view plain  copy
 
  1. def fun(i):  
  2.     return i%4+2  
  3. np.fromfunction(fun,(10,))  

array([ 2.,  3.,  4.,  5.,  2.,  3.,  4.,  5.,  2.,  3.])
   fromfunction必須支持多維數組,所以他的第二個參數必須是一個tuple,只能是(10,),(10)是錯誤的。
 
         
 
         
[python]  view plain  copy
 
  1. def fun2(i,j):  
  2.     return (i+1)*(j+1)  
  3. 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主要就是用進行元素的索取。
 
         
 
         
[python]  view plain  copy
 
  1. def loaddataSet(fileName):    
  2.     file=open(fileName)    
  3.     dataMat=[]  //  
  4.     for line in file.readlines():    
  5.         curLine=line.strip().split('\t')    
  6.         floatLine=map(float,curLine)//這里使用的是map函數直接把數據轉化成為float類型    
  7.         dataMat.append(floatLine)    
  8.     return dataMat    

上面的韓順返回最終的數據就是最初的list數據集,再根據不同的處理需求是轉化到array還是mat。其實array是mat的父類,能用mat的地方,array理論上都能傳入。
 
         
 
         

元素訪問:

 
[python]  view plain  copy
 
  1. arr[5] #5  
  2. arr[3:5] #array([3, 4])  
  3. arr[:5] #array([0, 1, 2, 3, 4])  
  4. arr[:-1]# array([0, 1, 2, 3, 4, 5, 6, 7, 8])  
  5. arr[:] #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])  
  6. arr[2:4]=100 # array([  0,   1, 100, 100,   4,   5,   6,   7,   8,   9])  
  7. arr[1:-1:2] #array([  1, 100,   5,   7]) 2 是間隔  
  8. arr[::-1] #array([  9,   8,   7,   6,   5,   4, 100, 100,   1,   0])   
  9. arr[5:2:-1]# -1的間隔表示從右向左所以5>2  #array([  5,   4, 100])  
 
   上面是array的一維數組的訪問方式,我們再來看看二維的處理方式
 
         
[python]  view plain  copy
 
  1. print c[1:2]#  c[1:2].shape-->(1L, 3L)  
  2. print c[1:2][0]  # shape-->(3L,)  

[[4 4 5]]
[4 4 5]

 
         
[python]  view plain  copy
 
  1. print c[1]  
  2. print c[1:2]  

[4 4 5]
[[4 4 5]]

 
         
[python]  view plain  copy
 
  1. print c[1][2]  
  2. print c[1:4]  
  3. print c[1:4][0][2]  

5
[[  4   4   5]
 [100 100 100]
 [100 100 100]]
5

   可以看出對於有:的表達最終的結果外面還嵌套一層list的[],。訪問的一定要注意,python最bug的就是,語法
靈活,不管怎樣寫索引語法都是正確的,但是最終的書結果卻讓你大跌眼鏡。
 
         
 
         
    還有array的索引最終產生的是一個一個原始數據的淺拷貝,還和原來的數據共用一塊兒內存
 
         
 
         
[python]  view plain  copy
 
  1. b=arr[1:6]  
  2. b[:3]=0  
  3. 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卻會直接發生深拷貝,數據指針全部帶走
 
         
[python]  view plain  copy
 
  1. list1=list(c)  
  2. list1[1]=0  
  3. list1  #上面修改的0並沒有被改變  

[array([1, 2, 3]), 0, array([100, 100, 100]), array([100, 100, 100])]

 
         
   除了這些之外還有自己的更加牛掰的方式(只能用array)
   1)使用布爾數組.感覺甚是強大,就不要自己寫什么判斷語句啦,注意這種方式得到結果不和原始數組共享空間。布爾索引僅僅適用於數組array,list沒資格用。布爾索引最終得到下標索引為true的數據。索引只能是布爾數組
 
         
 
         
[python]  view plain  copy
 
  1. a=np.array(a*2)  
  2. a>5  
  3. a[a>5]  #   
array([16, 32, 48, 64, 80, 16, 32, 48, 64, 80])
 
         
   
   2)列表索引
 
         
      列表索引可以是數組和list。返回的數據不和原來的數據共享內存。索引可以是list和array
 
         
[python]  view plain  copy
 
  1. x=np.arange(10)  
  2. index=[1,2,3,4,5]  
  3. arr_index=np.array(index)  
  4. print x  
  5. print x[index]  # list索引  
  6. 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
 
         
[python]  view plain  copy
 
  1. a=np.arange(10)  
  2. lista=list(a)  
  3. print a*2  
  4. 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的廣播

 
[python]  view plain  copy
 
  1. a = np.arange(0, 60, 10).reshape(-1, 1)  
  2. b = np.arange(0, 5)  
  3. print a  
  4. print b  
[[ 0]
 [10]
 [20]
 [30]
 [40]
 [50]]
[0 1 2 3 4]

[python]  view plain  copy
 
  1. 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]]

 


免責聲明!

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



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