您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關narray對象怎么在python中使用,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
numpy.narray創建
numpy.narray的構造方式挺多的,這里就不一一說明,因為一般情況下,在進行科學計算時是通過給定的數據文件來讀取的,而讀取時使用的是pandas,具體可參考官方文檔,或者參見這位大牛的文章。
numpy.narray.shape & numpy.narray.reshape
numpy.narray的形狀可以用numpy.narray.shape屬性來獲取,它返回的是narray形狀的tuple,反映了各個軸的長度。
na_a = np.array([1,2,3,4]) #長度為4的一維數組 na_b = np.array([[1,2,3,4],[5,6,7,8]]) #2行4列的二維數組 out: #print na_a [1 2 3 4] #print na_b [[1 2 3 4] [5 6 7 8]] #print na_a.shape (4,) #print na_b.shape (2, 4)
numpy.narray.shape相當于一個c++的public成員,不僅可以獲取,還可以通過它改變narray的形狀。當某一軸指定為-1時,該軸的長度將通過其他軸來計算。
na_b.shape = (4,2) na_a.shape = (2,-1) out: #print na_b [[1 2] [3 4] [5 6] [7 8]] #print na_a [[1 2] [3 4]]
需要注意的是:通過shape屬性改變narray的形狀時,并沒對narray元素內存中的位置改變,只是改變了外觀,僅僅是換了件馬甲。
當然,如果你熟悉了使用函數,不想使用屬性來改變形狀時,可以通過narray.reshape(),注意的是該函數返回的結果和原narray共享內存空間,換句話說,一個narray對象的改變將導致另一個narray也發生相應的改變。
na_c = na_b.reshape((4,2)) na_c[0][0] = 100 out: #print na_c [[1 2] [3 4] [5 6] [7 8]] #print na_c [[100 2] [ 3 4] [ 5 6] [ 7 8]] #print na_b [[100 2] [ 3 4] [ 5 6] [ 7 8]]
numpy.narray.dtype
narray元素的類型可以使用dtype屬性來獲取,當然也可以在構造narray對象時指定元素的類型,需要注意的是,在numpy中float是64位,而complex是128位的。這里的float和complex是python內置的數據類型,numpy也定義了自己的float等數據類型,而且更加的細化,比如float類型,numpy就有float16、float32、float64和float128.
af = np.array([1,2,3,4], dtype=float) ac = np.array([5,6,7,8], dtype=complex) af.dtype ac.dtype dtype('float64') dtype('complex128')
python的完整數據類型中有大部分是所占字節來細化的,完整的數據在typeDict中定義,可通過numpy.typeDict.values()來獲取完整類型。numpy在多維數組上的計算很高效,但是在數值對象計算上卻比python慢很多,所以在進行數值計算時應避免使用numpy。
numpy.narray.astype() 類型轉換
numpy.narray.astype() 可以對narray對象中元素逐一進行類型轉換。
a = np.array([1,2,3,4], dtype=np.float) a.dtype dtype('float64') b = a.astype(np.int32) b.dtype dtype('int32') c.dtype c = a.astype(np.complex) c.dtype dtype('complex128')
numpy.narray的自動生成
1.np.arange(start,end,step,dtype) 指定開始值、終值和步長生成一個等差數列,生成的narray中不包括end值。
2.np.linspace(start, end, element_nums, endpoint,dtype) 指定開始值、終值和元素個數生成一個等差數列,通過endpoint指定包不包括end,默認為True。
3.np.logspace(start, end, element_nums, base, endpoint,dtype) endpoint默認為True,base默認為10,該函數產生一個等比數列,元素為
4.np.zeros(dim,dtype)對維度為dim的narray對象初始化為0,數據類型為dtype
5.np.ones(dim, dtype) 對維度為dim的narray對象初始化為1,數據類型為dtype
6.np.empty(dim,dtype) 該函數相當于對narray對象分配內存空間,但不進行初始化,所以切不可認為產生的元素為0。
7.np.full(dim, val, dtype) 產生維度為dim的narray對象并且全部初始為val,前面的zeros()和ones()可看作該函數的特殊形式。
8.上面函數的like版本,即np.zeros_like(object) 、np.ones_like(object) 、np.empty_like(object) 、np.full_like(object) ,這里的object是narray對象,這些函數產生的narray對象和上面一樣,但narray的維度(shape)以及數據類型(dtype)是和傳入的參數一樣的,例如np.zeros_like(object) ==np.zeros(object.shape, object.dtype)。
9.fromstring(s, dtype)這個函數是比較又意思的,將字符串轉換為一個narray對象, 我們先看看這個函數輸出情況。
s="abcdefgh" np.fromstring(s) array([ 8.54088322e+194]) ## 這是什么鬼? ### 輸出一下dtype呢? dtype('float64')
顯然,這里是按照float64類型存放的,那如果換一個數據類型呢?
np.fromstring(s,dtype=np.int8) array([ 97, 98, 99, 100, 101, 102, 103, 104], dtype=int8)
這個學過c語言的都應該知道是ASCII編碼,也就可以看出,在python中一個字符是占8位,即一個字節的,繼續看:
np.fromstring(s,dtype=np.int16) array([25185, 25699, 26213, 26727], dtype=int16)
這里改變數據類型位2個字節,那么應該是兩個字符聯立一起表示一個int16,25185=98*256+97,高位存放在低字節中,這是小端模式。OK,那如果我現在要存放的是[‘a','b'…'h']這樣的narray對象呢?數據類型是什么?應該是‘|s1'
np.fromstring(s,'|S1') array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], dtype='|S1')
frombuffer()也可以創建的narray對象,但此時創建的narray對象和原字符串是內存共享的,學過c++的都知道,string類型是只讀類型,無法修改,所以在frombuffer()創建的narray無法做修改,如果要修改,請用fromstring()。
. fromfunction(fun, dim)通過自定義函數接口來創建narray對象,fun是一個函數名(看作指針),dim是一個創建對象的維度。
def fun(i): return i%4+1 np.fromfunction(fun,(10,)) array([ 1., 2., 3., 4., 1., 2., 3., 4., 1., 2.])
可見利用fromfunction()創建narray時,參數i是從0開始自增的,自增的次數是維度的大小給定的,上面給定的維度位(10,),是一個一維數組,i從0自增到9(共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.]])
行可以看作j的自增,列可以看作i的自增,所以可以看作是兩個for循環。
numpy.narray的元素存取
可以按照python中list存取元素的方式。
a = np.arange(10) #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) a[5] #5 a[3:5] #[3,4] a[:5] #[0,1,2,3,4] a[:-1] #[0, 1, 2, 3, 4, 5, 6, 7, 8] ### 也可以指定步長,通過第三個數指定 a[1:-1:2] #從開始到結束,沒隔兩個數取一次 array([1, 3, 5, 7]) a[5:1:-2] #反向取 array([5, 3])
注意,通過這種方式取的新narray和原始narray內存共享,所以任何一個改變,另一個也將改變。 除此之外,numpy還提供了一下幾個存取方式: 使用list存取,list的每個元素作為下標,這種方式得到的新narray和原始narray不共享內存。
a = np.arange(10) a[[1,1,7,7]] #array([1, 1, 7, 7])
使用narray提取新數組,narray的元素作為下標,得到的新narray維度和參數narray維度相同。這個有點繞,看個例子吧:
a[np.array([2,1,3,6])] #array([2, 1, 3, 6]) a[np.array([[2,1,3,6],[7,4,6,1]])] ## ## array([[2, 1, 3, 6], [7, 4, 6, 1]])
使用bool數組提取,提取bool數組中為True的下標元素:
a[np.array([True, False,True,False,False,False,True,False,False,False])] ## array([0, 2, 6]) a[np.array([True,False,True,False,False,False,True,False,False,False])]=-1,-2,-3 print a #array([-1, 1, -2, 3, 4, 5, -3, 7, 8, 9])
多維數組
請先看一張圖:
左邊是用切片方式提取右邊6*6的narray對象元素。這種提取元素方式和原narray對象內存共享。
這里個人的理解,利用切片方式提取的新narray和原narray是內存共享的,而使用列表、bool數組等方式則不共享,原因很簡單,利用切片方式,例如a[3:5],是從第三個元素到第5個元素(不包括),那么是用元素所占字節來移動的,就像c中的指針,這樣比較便利。而其他方式是用下標,這些下標往往不連續,如果用指針方式的話則要來回移動,比較麻煩。所以不提供內存共享這種方式。
在這之前我們使用切片都是通過在[]中指定起點、終點以及步長,如果要單獨創建切片對象呢?使用slice對象,創建的方式很簡單,把[]中的:替換為None。
a = np.arange(0,60,10).reshape(-1,1)+np.arange(6) ### 廣播,后面會說到 array([[ 0, 1, 2, 3, 4, 5], [10, 11, 12, 13, 14, 15], [20, 21, 22, 23, 24, 25], [30, 31, 32, 33, 34, 35], [40, 41, 42, 43, 44, 45], [50, 51, 52, 53, 54, 55]]) a[::2,2:] ## array([[ 2, 3, 4, 5], [22, 23, 24, 25], [42, 43, 44, 45]]) idx = slice(None,None,2),slice(2,None) a[idx] ## array([[ 2, 3, 4, 5], [22, 23, 24, 25], [42, 43, 44, 45]])
同時,numpy提供了IndexExpression類的對象s_來方便slice的創建。
np.s_[::2,2:] ## (slice(None, None, 2), slice(2, None, None))
結構體數組
numpy提供了和c類似的結構體數組,并且相互之間能夠讀取,以一個例子來說明:
## 創建persontype類型 persontype=np.dtype({ 'names':['name','age','weight'], 'formats':['S30','i','f']}, align=True) ## 創建結構體數組 a=np.array([("zhang",20,55.5), ("wang",24,65.2)], dtype=persontype)
persontype有兩個key,names和formats,names是以字典的方式標明結構體所含的字段,formats是對相應字段的數據類型。S30表示長度不超過30個字節的字符串,i相當于np.int32,f相當于np.float32,下面創建結構體數組的時候指定數據類型是我們創建的persontype。
## print a array([('zhang', 20, 55.5 ), ('wang', 24, 65.19999695)], dtype={'names':['name','age','weight'], 'formats':['S30','<i4','<f4'], 'offsets':[0,32,36], 'itemsize':40, 'aligned':True}) ## print a[0] ('zhang', 20, 55.5) ## a[0].dtype dtype({'names':['name','age','weight'], 'formats':['S30','<i4','<f4'], 'offsets':[0,32,36], 'itemsize':40}, align=True) ## a[0]["name"] 'zhang' b=a['age'] ## 20 24 b[0]=50 ## print a[0] ('zhang', 50, 55.5)
通過tostring()和tofile()可以將結構體數組寫入文件,并可以通過c讀取,由于c中的結構體存在對齊,所以在python創建結構體數組時也需要使用相應的對齊方式,這一點通過align來指定,True為對齊,False不對齊。
narray內存結構
以二維narray對象為例,我們來看看narray對象在內存中的結構。
a = np.array([[0,1,2],[3,4,5],[6,7,8]], dtype=np.float32)
該二維數組的結構如下圖:
左邊時一個結構體,描述了該narray對象的基本信息,包括數據類型(np.float32)、維度(軸的數量)、每個軸的數據個數、每個軸相鄰元素的字節差、最后是存放數據的內存地址。通過切片方式得到的新narray就是在data字段表示的內存上獲得原始narray的視圖,我們來看看:
b=a[::2,::2] ## b array([[ 0., 2.], [ 6., 8.]], dtype=float32) ## b.strides (24, 8)
獲得的新narray.strides發生了變化,而這個變化也剛好是每個軸相鄰元素跨越的字節數。narray的數據在內存上的排列有兩種形式,分別是C和FORTRAN格式,上面我們展示的就是C的格式,第0軸是最上位的,也就是說,第0軸作為行,所以第0軸的相鄰元素跨越的字節數是最多的(比如這里為3*4=12),而FORTRAN結構與C格式相反,它是第1軸跨越的字節數最多。numpy默認是C格式,如果想改成FORTRAN的格式,只需要在創建narray的時候設置order=‘F'。narray的flags屬性描述了存儲區的一些屬性:
## a.flags C_CONTIGUOUS : True #C語言格式 F_CONTIGUOUS : False #Fortran語言格式 OWNDATA : True #數組是否擁有該存儲區,如果是一個narray的視圖則不擁有 WRITEABLE : True #是否可寫 (改變其中數據) ALIGNED : True # 對齊 UPDATEIFCOPY : False
OK,這里引出一個東東,如果要將a進行轉置,我們是需要將需要將a順時針旋轉90°,那么還有上面簡單的方法?我們先看看a.T.flags:
## a.T.flags C_CONTIGUOUS : False F_CONTIGUOUS : True OWNDATA : False WRITEABLE : True ALIGNED : True UPDATEIFCOPY : False
關于narray對象怎么在python中使用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。