注:本文采用 import numpy as np 的方式導(dǎo)入模塊硕勿,后續(xù)不再提示
一迹炼、數(shù)組是什么(ndarray)
所謂數(shù)組仔燕,是有序的元素序列。若將有限個類型相同的變量的集合命名葡秒,那么這個名稱為數(shù)組名姻乓。組成數(shù)組的各個變量稱為數(shù)組的分量嵌溢,也稱為數(shù)組的元素,有時也稱為下標(biāo)變量蹋岩。用于區(qū)分?jǐn)?shù)組的各個元素的數(shù)字編號稱為下標(biāo)赖草。數(shù)組是在程序設(shè)計中,為了處理方便剪个, 把具有相同類型的若干元素按無序的形式組織起來的一種形式秧骑。這些無序排列的同類數(shù)據(jù)元素的集合稱為數(shù)組
二、數(shù)據(jù)類型和結(jié)構(gòu)數(shù)組
1.數(shù)據(jù)類型
numpy支持很多數(shù)據(jù)類型扣囊,并且可以使用 astype 方法轉(zhuǎn)換數(shù)組的數(shù)據(jù)類型
完整的 ndarry 數(shù)據(jù)類型可以用下面的方法進(jìn)行查看:
>>> print set(np.typeDict.values())
set([<type 'numpy.int8'>, <type 'numpy.uint8'>, <type 'numpy.float16'>, <type 'numpy.timedelta64'>, <type 'num
py.bool_'>, <type 'numpy.object_'>, <type 'numpy.int16'>, <type 'numpy.uint16'>, <type 'numpy.float32'>, <type
'numpy.complex64'>, <type 'numpy.string_'>, <type 'numpy.int32'>, <type 'numpy.uint32'>, <type 'numpy.float64
'>, <type 'numpy.complex128'>, <type 'numpy.unicode_'>, <type 'numpy.int32'>, <type 'numpy.uint32'>, <type 'nu
mpy.float64'>, <type 'numpy.complex128'>, <type 'numpy.void'>, <type 'numpy.int64'>, <type 'numpy.uint64'>, <t
ype 'numpy.datetime64'>])
2.結(jié)構(gòu)數(shù)組
數(shù)組數(shù)據(jù)的類型可以由用戶自定義乎折。自定義數(shù)據(jù)類型是一種異質(zhì)結(jié)構(gòu)數(shù)據(jù)類型,通常用來記錄一行數(shù)據(jù)或一系列數(shù)據(jù)侵歇,即結(jié)構(gòu)數(shù)組骂澄。(我個人覺得跟數(shù)據(jù)庫建表插入數(shù)據(jù)有點(diǎn)類似)
例1:
- 第一步:使用 dtype 函數(shù)自定義字段類型
>>> exlist=np.dtype([('name',np.str_,50),('volume',np.int32)])
>>> exlist
dtype([('name', 'S50'), ('volume', '<i4')])
- 第二步:定義好數(shù)據(jù)類型后,使用 array 函數(shù)惕虑,便可以構(gòu)造結(jié)構(gòu)數(shù)組
>>> lists=np.array([('Blue',22),('Sony',55),('Apple',10),('KK',100)],dtype=exlist)
>>> # dtype 指定第一步創(chuàng)建的結(jié)構(gòu)數(shù)組 exlist
>>> lists
array([('Blue', 22), ('Sony', 55), ('Apple', 10), ('KK', 100)],
dtype=[('name', 'S50'), ('volume', '<i4')])
例2:
另外還可以使用描述結(jié)構(gòu)烈性的各個字段的字典來定義結(jié)構(gòu)數(shù)組坟冲。該字典需要兩個鍵:names 和 formats
- names:定義結(jié)構(gòu)中每個字段的名稱
- formats:定義每個字段的類型
>>> exdict=np.dtype({'names':['name','volume'],'formats':['S50','i']})
>>> exdict
dtype([('name', 'S50'), ('volume', '<i4')])
>>>
>>> list_new=np.array([('Blue',22),('Sony',55),('Apple',10),('KK',100)],dtype=exdict)
>>> list_new
array([('Blue', 22), ('Sony', 55), ('Apple', 10), ('KK', 100)],
dtype=[('name', 'S50'), ('volume', '<i4')])
結(jié)構(gòu)數(shù)組可以直接使用字段名進(jìn)行索引和切片
三、索引與切片
1.基本索引和切片
- " [ ] ":用中括號選定下標(biāo)來進(jìn)行數(shù)組的索引與切片
- " : " : 用冒號分隔起止位置與間隔
單冒號 [ 開始:結(jié)束 ]
雙冒號 [ 開始:結(jié)束:步長]
- "溃蔫," : 表示不同維度
- " ... ":表示遍歷剩下的維度
例子這里就不做介紹了健提,跟python的基礎(chǔ)庫中索引差不多
多維數(shù)組的索引與切片也類似,這里展示幾個例子:
>>> b=np.arange(24).reshape(2,3,4) # 使用 reshape 來定義多維數(shù)組形狀
>>> b
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> b[1,2,1] # 2層3行第2個數(shù)
21
>>> b[0,2,:] # 1層 3行 所有數(shù)
array([ 8, 9, 10, 11])
>>> b[0,...] # 第一層 所有的數(shù)字伟叛,多個冒號可以用 ... 來代替私痹,省略... 也可以
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b[:,1] # 選取各層第二行數(shù)字
array([[ 4, 5, 6, 7],
[16, 17, 18, 19]])
>>> b[:,:,1] # 選取各層第二列的數(shù)字
array([[ 1, 5, 9],
[13, 17, 21]])
>>> b[...,1]
array([[ 1, 5, 9],
[13, 17, 21]])
>>> b[0,::2,-2] # 在0層中每隔一行選取改行倒數(shù)第二個數(shù)
array([ 2, 10])
2.邏輯索引
邏輯索引又稱布爾索引、條件索引
也就是數(shù)學(xué)里面的 或痪伦、且侄榴、非
注:邏輯運(yùn)算符 and 和 or 在布爾型數(shù)組中無效雹锣,需使用 &(且)网沾、|(或)之類的布爾算術(shù)運(yùn)算符
依舊使用前面創(chuàng)建的數(shù)組 b,例:
>>> b[b>=15]
array([15, 16, 17, 18, 19, 20, 21, 22, 23])
>>> b[~(b>=15)]
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
>>> b[(b>=5)&(b<=15)]
array([ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
>>> b_bool1=np.array([False,True],dtype=bool) # 使用bool 索引蕊爵,需要先創(chuàng)建布爾型的數(shù)組
>>> b[b_bool1]
array([[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
# 使用布爾型數(shù)組去索引辉哥,每級需有True 并且正確對應(yīng),否則會類型錯誤拋異常
>>> b_bool2=np.array([False,True,True],dtype=bool)
>>> b_bool3=np.array([False,True,True,False],dtype=bool)
>>> b[b_bool1,b_bool2]
array([[16, 17, 18, 19],
[20, 21, 22, 23]])
>>> b[b_bool1,b_bool2,b_bool3] # 可去思考下為什么結(jié)果是 17 和 22
array([17, 22])
3.花式索引
利用整數(shù)數(shù)組進(jìn)行索引,其可使用指定順序?qū)?shù)組提取子集
例1:
>>> b[[[0],[1,2],[2,3]]] # 提取第0層第1行第2列攒射、第0層第2行第3列
array([ 6, 11])
注:b[0][1] 等價于 b[0,1]
ix_ 函數(shù)可將若干一維整數(shù)數(shù)組轉(zhuǎn)換為一個用于選取矩形區(qū)域的索引器:(增強(qiáng)可讀性)
例2:
>>> b[np.ix_([1,0],[2,1],[0,3,2])]
array([[[20, 23, 22],
[16, 19, 18]],
[[ 8, 11, 10],
[ 4, 7, 6]]])
# 先取第1層 第2行 的0,3,2 號元素 和 第1層 第1行的 0,3,2號元素
# 然后再取 第0層 第2行 的0,3,2 號元素 和 第0層 第1行的 0,3,2號元素
注:可以思考下 ix_ 和上面方式的區(qū)別醋旦,ix_ 有點(diǎn)類似于遍歷,而之前的方式有點(diǎn)類似于坐標(biāo)
數(shù)組切片是原始數(shù)據(jù)的視圖(view)会放,與原始數(shù)據(jù)共享一塊數(shù)據(jù)存儲空間饲齐,即:數(shù)據(jù)不會被復(fù)制,視圖上的任何修改都會直接反映到原始數(shù)據(jù)咧最。如果需要數(shù)組切片是一個副本而不是視圖捂人,可以使用 copy 方法進(jìn)行淺復(fù)制:
>>> b_slice=b[0,1,1:3]
>>> b_copy=b[0,1,1:3].copy() # 采用淺復(fù)制
>>> b_slice
array([5, 6])
>>> b_copy
array([5, 6])
>>> b_slice[1]=666 # 將數(shù)組元素重賦值
>>> b_slice
array([ 5, 666])
>>> b # 可以看到原始數(shù)組已經(jīng)被改變
array([[[ 0, 1, 2, 3],
[ 4, 5, 666, 7],
[ 8, 9, 10, 11]],
[[ 12, 13, 14, 15],
[ 16, 17, 18, 19],
[ 20, 21, 22, 23]]])
>>>
>>> b_copy[1]=999 # 對淺復(fù)制的組元素重新賦值
>>> b_copy
array([ 5, 999])
>>> b
array([[[ 0, 1, 2, 3],
[ 4, 5, 666, 7],
[ 8, 9, 10, 11]],
[[ 12, 13, 14, 15],
[ 16, 17, 18, 19],
[ 20, 21, 22, 23]]]) # 可以看到原始數(shù)據(jù)沒有發(fā)生變化
而花式索引跟數(shù)組切片不一樣御雕,它總是將數(shù)據(jù)復(fù)制到新的數(shù)組中
四、數(shù)組的屬性
數(shù)組的屬性包括維度滥搭、大小酸纲、數(shù)據(jù)類型,等
定義個數(shù)組來解析
>>> ac=np.arange(12)
>>> ac.shape=(2,2,3) # 使用 shape 來定義數(shù)組的形狀
>>> ac
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
-
思考:shape定義數(shù)組形狀和 reshape 定義數(shù)組形狀有什么區(qū)別
shape 直接修改內(nèi)存地址中數(shù)組的形狀而 reshape 不會修改瑟匆,即 shape會修改原始數(shù)組闽坡,reshape 不會修改
屬性 | 含義 | 示例 | 結(jié)果 |
---|---|---|---|
shape | 返回數(shù)組的形狀,如行愁溜、列疾嗅、層等 | ac.shape | (2,2,3) |
ndim | 返回數(shù)組的維數(shù)或數(shù)組軸的個數(shù)(有多少對 [ ] 就有多少維度) | ac.ndim | 3 |
dtype | 返回數(shù)組中各元素的類型 | ac.dtype | dtype('int64') |
size | 返回數(shù)組元素的總個數(shù) | ac.size | 12 |
itemsize | 返回數(shù)組中的元素在內(nèi)存中所占的字節(jié)數(shù) | ac.itemsize | 8 |
nbyte | 返回數(shù)組所占的存儲空間,即 itemsize 與 size 的乘積 | ac.nbyte | 96 |
T | 返回數(shù)組的轉(zhuǎn)置數(shù)組 | print ac.T | [[[ 0 6] [ 3 9]] [[ 1 7] [ 4 10]] [[ 2 8] [ 5 11]]] |
flat | 展平迭代器祝谚,像遍歷一維數(shù)組一樣去遍歷任意多維數(shù)組宪迟,也可從迭代器中獲取指定數(shù)組元素 | acf=ac.flat;acf for i in acf: print i, acf[5:] acf[[1,3,11]]=100 print ac |
<numpy.flatiter object at 0x000000000933A8D0> 0 1 2 3 4 5 6 7 8 9 10 11 array([ 5, 6, 7, 8, 9, 10, 11]) [[[ 0 100 2] [100 4 5]] [[ 6 7 8] [ 9 10 100]]] |
五、數(shù)組排序
這里暫時只列幾個進(jìn)行介紹交惯,其他的可以上官文查看
1. numpy 有以下多種排序:
- sort : 返回排序后的數(shù)組
- lexsort: 根據(jù)鍵值的字典序進(jìn)行排序
- argsort: 返回數(shù)組排序后的下標(biāo)
- msort:沿著第一個軸排序
- sort_complex : 對復(fù)數(shù)按照先實后虛的順序進(jìn)行排序
1.1 numpy.sort(a, axis=-1, kind='quicksort', order=None)
使用方法:numpy.sort(a)
參數(shù)說明:
- axis:排序沿著數(shù)組的方向次泽,0表示按行,1表示按列
- kind:排序的算法席爽,提供了快排意荤、混排、堆排
- order:不是指的順序只锻,以后用的時候再去分析這個
- a:要排序的數(shù)組
作用效果:對數(shù)組a排序玖像,返回一個排序后的數(shù)組(與a相同維度),a不變
例:
>>> s=np.array([1,2,3,4,7,54,32,23,2,5,8,3])
>>> np.sort(s)
array([ 1, 2, 2, 3, 3, 4, 5, 7, 8, 23, 32, 54])
>>> s
array([ 1, 2, 3, 4, 7, 54, 32, 23, 2, 5, 8, 3])
1.2 numpy.argsort(a, axis=-1, kind='quicksort', order=None)
使用方法:numpy.argsort(a)
參數(shù)跟上面的一樣
作用效果:對數(shù)組a排序齐饮,返回一個排序后索引捐寥,a不變
例:
>>> np.argsort(s) # 顯示排序后的下標(biāo)
array([ 0, 1, 8, 2, 11, 3, 9, 4, 10, 7, 6, 5], dtype=int64)
>>> s[np.argsort(-s)] # 對s進(jìn)行降序排序,原理就是先獲取下標(biāo)再取反祖驱,通過取反的下標(biāo)得出結(jié)果
array([54, 32, 23, 8, 7, 5, 4, 3, 3, 2, 2, 1])
>>> s # 原數(shù)組不改變
array([ 1, 2, 3, 4, 7, 54, 32, 23, 2, 5, 8, 3])
1.3 numpy.lexsort
指定排序的順序
例:
>>> a=[1,5,1,4,3,4,4]
>>> b=[9,4,0,4,0,2,1]
>>> ind=np.lexsort((b,a)) # 先按a排序握恳,再按b排序,得到的ind是下標(biāo)
>>> [(a[i],b[i]) for i in ind]
[(1, 0), (1, 9), (3, 0), (4, 1), (4, 2), (4, 4), (5, 4)]
>>> print ind
[2 0 4 6 5 3 1]
2. ndarry 的排序:
2.1 ndarray.sort(axis=-1, kind='quicksort', order=None)
使用方法:a.sort
參數(shù)說明:
axis:排序沿著數(shù)組的方向捺僻,0表示按行乡洼,1表示按列
kind:排序的算法,提供了快排匕坯、混排束昵、堆排
order:不是指的順序,以后用的時候再去分析這個
作用效果:對數(shù)組a排序葛峻,排序后直接改變了a
>>> s.sort()
>>> s
array([ 1, 2, 2, 3, 3, 4, 5, 7, 8, 23, 32, 54])
在多維數(shù)組中锹雏,可以指定按照數(shù)組的軸進(jìn)行排序:
>>> s_r=np.array([3,23,52,34,52,3,5,645,34,7,85,23]).reshape(6,2)
>>> s_r
array([[ 3, 23],
[ 52, 34],
[ 52, 3],
[ 5, 645],
[ 34, 7],
[ 85, 23]])
>>> s_r.sort(axis=1) # 對行進(jìn)行排序
>>> s_r
array([[ 3, 23],
[ 34, 52],
[ 3, 52],
[ 5, 645],
[ 7, 34],
[ 23, 85]])
>>> s_r.sort(axis=0) # 對列進(jìn)行排序
>>> s_r
array([[ 3, 23],
[ 3, 34],
[ 5, 52],
[ 7, 52],
[ 23, 85],
[ 34, 645]])
六、數(shù)組維度
數(shù)組的維度可以進(jìn)行變換术奖,如行列互換礁遵、降維等匿辩。numpy 中可以使用 reshape 函數(shù)改變數(shù)組的維數(shù),使用 ravel 函數(shù)榛丢、flatten 函數(shù)可將數(shù)組展平為一維數(shù)組铲球。
1. 展平
將數(shù)組轉(zhuǎn)為一維數(shù)組
直接來例子吧:
>>> b=np.arange(24).reshape(2,3,4)
>>> b
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>>
>>> b.ndim
3
>>> br=np.ravel(b) # 將數(shù)組轉(zhuǎn)為一維數(shù)組
>>> br
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23])
>>> br.ndim
1
reshape 同樣也能轉(zhuǎn)成一維數(shù)組的樣子,但是不是真正的一維數(shù)組:
>>> brsh=b.reshape(1,1,24)
>>> brsh
array([[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23]]])
>>> brsh.ndim
3
ndarray.flatten 方法也能將數(shù)組展平晰赞,效果與 numpy.ravel 相同稼病,區(qū)別就是 flatten 會分配內(nèi)存保存結(jié)果,ravel 函數(shù)只是返回數(shù)組的一個視圖
>>> b.flatten()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23])
2. 維度改變
數(shù)組 reshape 方法和 resize 方法均可改變數(shù)組的維度和數(shù)組尺寸掖鱼,如:
>>> bd=b.reshape(4,6) # 這里再次提示然走,reshape不改變原始值,所以采用賦值的方式
>>> bd
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
也可以使用 shape 來直接改變數(shù)組的尺寸或維度戏挡,resize方法跟 shape 賦值一樣:
>>> b.shape=(1,1,24)
>>> b
array([[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23]]])
>>> bd.resize(1,1,24)
>>> bd
array([[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23]]])
shape 和 resize 均會改變原始數(shù)組
3. 轉(zhuǎn)置
轉(zhuǎn)置即把數(shù)組的尺寸大小互換芍瑞,可使用 numpy 中的 transpose 函數(shù)也可以使用之前提到的 nadarry.T :
>>> b.shape=(3,4,2)
>>> b
array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]],
[[16, 17],
[18, 19],
[20, 21],
[22, 23]]])
>>> np.transpose(b) # 等價于 b.T
array([[[ 0, 8, 16],
[ 2, 10, 18],
[ 4, 12, 20],
[ 6, 14, 22]],
[[ 1, 9, 17],
[ 3, 11, 19],
[ 5, 13, 21],
[ 7, 15, 23]]])
>>> np.transpose(b).shape
(2, 4, 3) # 可以看到數(shù)組的結(jié)構(gòu)被互換了
七、數(shù)組組合
這里只介紹幾個主要的組合函數(shù)
- 水平組合(hstack)
- 垂直組合(vstack)
- 深度組合(dstack)
- 列組合(colume_stack)
- 行組合(row_stack)
1. 水平組合
把所有參加組合的數(shù)組拼接起來褐墅,各數(shù)組行數(shù)應(yīng)當(dāng)相等
>>> a=np.arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> b=np.array([[0,11,22,33],[44,55,66,77],[88,99,00,11]])
>>> b
array([[ 0, 11, 22, 33],
[44, 55, 66, 77],
[88, 99, 0, 11]])
>>> np.hstack((a,b)) # 因為 hstack 函數(shù)的參數(shù)只有一個拆檬,所以把要參加組合的數(shù)組對象以元祖的形式傳參
array([[ 0, 1, 2, 0, 11, 22, 33],
[ 3, 4, 5, 44, 55, 66, 77],
[ 6, 7, 8, 88, 99, 0, 11]])
如果參加組合的數(shù)組行不一致,則會報錯:
>>> c=np.array([[0,11,22],[44,55,66],[88,99,00],[22,33,44]])
>>> print c
[[ 0 11 22]
[44 55 66]
[88 99 0]
[22 33 44]]
>>> np.hstack((a,c))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\numpy\core\shape_base.py", line 288, in hstack
return _nx.concatenate(arrs, 1)
ValueError: all the input array dimensions except for the concatenation axis must match exactly
2. 垂直組合
垂直組合即吧所有參加組合的數(shù)組追加在一起妥凳,各數(shù)組列數(shù)應(yīng)一致:
>>> np.vstack((a,c))
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 11, 22],
[44, 55, 66],
[88, 99, 0],
[22, 33, 44]])
此外再介紹一個函數(shù)竟贯,concatenate 可以直接進(jìn)行水平組合以及垂直組合:
numpy.concatenate((a1,a2,...),axis=0)
參數(shù)解釋:
a1,a2,... : 需要拼接的矩陣
axis : 拼接的方式,0 表示按列(也就是追加逝钥,垂直組合)
1表示按行(也就是水平組合)
例:
>>> np.concatenate((a,b),axis=1) # 水平組合
array([[ 0, 1, 2, 0, 11, 22, 33],
[ 3, 4, 5, 44, 55, 66, 77],
[ 6, 7, 8, 88, 99, 0, 11]])
>>>
>>> np.concatenate((a,c),axis=0) # 垂直組合
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 11, 22],
[44, 55, 66],
[88, 99, 0],
[22, 33, 44]])
3. 深度組合
深度組合即將參加組合的個數(shù)組相同位置的數(shù)組組合在一起屑那,我的理解就是下標(biāo)相同的組合在一起,所以需要數(shù)組的維度相同
例:
>>> d=np.delete(b,3,axis=1)
# delete 函數(shù)可以刪除數(shù)組中的指定數(shù)據(jù)艘款,axis=1 表示列持际, axis=0 表示行
>>> d
array([[ 0, 11, 22],
[44, 55, 66],
[88, 99, 0]])
>>> np.dstack((a,d))
array([[[ 0, 0],
[ 1, 11],
[ 2, 22]],
[[ 3, 44],
[ 4, 55],
[ 5, 66]],
[[ 6, 88],
[ 7, 99],
[ 8, 0]]])
4. 列組合
column_stack 對于一維數(shù)組按列的方向進(jìn)行組合,對于二維數(shù)組和水平組合相同
>>> a1=np.arange(4)
>>> a2=np.arange(4)*2
>>> np.column_stack((a1,a2))
array([[0, 0],
[1, 2],
[2, 4],
[3, 6]])
5. 行組合
row_stack 對于一維數(shù)組按行的方向組合哗咆,對于二維數(shù)組和垂直組合效果相同
>>> np.row_stack((a1,a2))
array([[0, 1, 2, 3],
[0, 2, 4, 6]])
八蜘欲、數(shù)組分拆
分拆類型分為:
- 水平分拆(hsplit)
- 垂直分拆(vsplit)
- 深度分拆(dsplit)
1. 水平分拆
把數(shù)組沿著水平方向進(jìn)行分拆,每個數(shù)組分拆成單個元素
>>> a=np.arange(9).reshape(3,3)
>>> print a
[[0 1 2]
[3 4 5]
[6 7 8]]
>>>
>>> ahs=np.hsplit(a,3)
>>> print ahs
[array([[0],
[3],
[6]]), array([[1],
[4],
[7]]), array([[2],
[5],
[8]])]
>>> type(ahs) # 分拆的結(jié)果返回是列表岳枷,列表中的元素才是numpy數(shù)組
<type 'list'>
>>> type(ahs[1])
<type 'numpy.ndarray'>
2. 垂直分拆
把數(shù)組沿著垂直方向進(jìn)行分拆:
>>> np.vsplit(a,3)
[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
同樣水平分拆和垂直分拆都可以調(diào)用 split 函數(shù)進(jìn)行分拆
>>> np.split(a,3,axis=1) # axis=1 為水平拆分
[array([[0],
[3],
[6]]), array([[1],
[4],
[7]]), array([[2],
[5],
[8]])]
>>> np.split(a,3,axis=0) # axis=0 為垂直拆分
[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
3. 深度拆分
按照深度方向分拆3個維度以上(含)的數(shù)組:
>>> ads=np.arange(12)
>>> ads.shape=(2,2,3)
>>> print ads
[[[ 0 1 2]
[ 3 4 5]]
[[ 6 7 8]
[ 9 10 11]]]
>>> np.dsplit(ads,3)
[array([[[0],
[3]],
[[6],
[9]]]), array([[[ 1],
[ 4]],
[[ 7],
[10]]]), array([[[ 2],
[ 5]],
[[ 8],
[11]]])]
九芒填、ufunc運(yùn)算
ufunc是universal function的縮寫呜叫,它是一種能對數(shù)組的每個元素進(jìn)行操作的函數(shù)空繁。NumPy內(nèi)置的許多ufunc函數(shù)都是在C語言級別實現(xiàn)的,因此它們的計算速度非持烨欤快盛泡。這些函數(shù)可以進(jìn)行四則運(yùn)算,比較運(yùn)算以及布爾運(yùn)算等娱颊“了校可以使用“out=” 關(guān)鍵字來指定把函數(shù)返回結(jié)果存儲在指定數(shù)組中凯砍,用戶可以用 frompyfunc 函數(shù)來自定義 ufunc 函數(shù)。
我這里只介紹部分 ufunc 運(yùn)算拴竹,感興趣的可以去找下相關(guān)資料
1. 函數(shù)運(yùn)算悟衩、比較運(yùn)算、布爾運(yùn)算
>>> a1=np.arange(0,10)
>>> a1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a2=np.arange(0,20,2)
>>> a2
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
>>> a3=np.add(a1,a2,out=a1) # numpy.add 兩個數(shù)組相加栓拜,out=后面的數(shù)組需是事先定義過的數(shù)組座泳,out=關(guān)鍵字可以省略
>>> print a3,a1
[ 0 3 6 9 12 15 18 21 24 27] [ 0 3 6 9 12 15 18 21 24 27]
>>> id(a3) == id(a1)
True
# 從運(yùn)算結(jié)果可以看書,使用 out 關(guān)鍵字指定數(shù)組與通常使用賦值方式得到的函數(shù)運(yùn)算結(jié)果數(shù)組是綁定到同一個對象的
>>> a1 > a2
array([False, True, True, True, True, True, True, True, True,
True])
>>> any(a1>a2) # 或
True
>>> all(a1>a2) # 且
False
2. 自定義 ufunc 函數(shù)
有時候用戶需要自定義函數(shù)對數(shù)組元素進(jìn)行操作幕与,這時可以用 frompyfun 函數(shù)將一個計算單個元素的函數(shù)轉(zhuǎn)換成 ufunc 函數(shù)挑势。frompyfunc 的調(diào)用格式為:
frompyfunc(func, n_in, n_out) n_in、n_out分別表示輸入?yún)?shù)的個數(shù)和返回值的個數(shù)
比如啦鸣,在考試中由于出題難度偏大潮饱,需要對所有人的分?jǐn)?shù)進(jìn)行提升,并且保持分?jǐn)?shù)的相對位置不變诫给,可編制一個函數(shù):
def liftscore(n):
n_new=np.sqrt((n^2)*100) #平方根
return n_new
使用 frompyfunc 將其自定義為 ufunc 函數(shù)香拉,并對數(shù)組對象進(jìn)行操作:
>>> score=np.array([87,77,56,100,60])
>>> score_1=np.frompyfunc(liftcore,1,1)(score)
>>> score_1
array([92.19544457292888, 88.88194417315589, 76.15773105863909,
100.99504938362078, 78.74007874011811], dtype=object)
注意:frompyfunc 轉(zhuǎn)換的 ufunc 函數(shù)所返回數(shù)組的元素類型是 object。因此還需要調(diào)用數(shù)組的 astype 方法以將其轉(zhuǎn)換為浮點(diǎn)數(shù)組中狂。
>>> score_1=score_1.astype(float)
使用 vectorize 可以實現(xiàn) frompyfunc 類似的功能缕溉,但它可以通過 otypes 參數(shù)指定返回數(shù)組的元素類型。otypes 參數(shù)可以是一個表示元素類型的字符串吃型,也可以是一個類型列表证鸥,使用列表可以描述多個返回數(shù)組的元素類型:
>>> score_2=np.vectorize(liftcore,otypes=[float])(score)
>>> any(score_1==score_2)
True
3. 廣播 (這兩塊后續(xù)再補(bǔ)上吧。我自己都還沒玩6)
4. ufunc 的方法
十勤晚、矩陣
矩陣是 numpy 提供的另外一種數(shù)據(jù)類型枉层,可以使用 mat 或 matrix 函數(shù)將數(shù)組轉(zhuǎn)化為矩陣
>>> m1=np.mat([[1,2,3],[4,5,6]])
>>> m1
matrix([[1, 2, 3],
[4, 5, 6]])
>>> m1*8
matrix([[ 8, 16, 24],
[32, 40, 48]])
>>>
>>> m2=np.matrix([[1,2,3],[4,5,6],[7,8,9]])
>>>
>>> m1*m2 # 矩陣乘法:兩個矩陣的乘法僅當(dāng)?shù)谝粋€矩陣的列數(shù)和另一個矩陣的行數(shù)相等時才能定義
matrix([[30, 36, 42],
[66, 81, 96]])
上面計算的流程:(不知道簡書矩陣markdown 怎么寫,心塞)
1*1+2*4+3*7=30,1*2+2*5+3*8=36,1*3+2*6+3*9=42
4*1+5*4+6*7=66,4*2+5*5+6*8=81,4*3+5*6+6*9=96
一般情況 python 中都會使用數(shù)組進(jìn)行運(yùn)算赐写,如果實在要使用矩陣進(jìn)行運(yùn)算的話鸟蜡,自行使用
dir 函數(shù)查看矩陣對象的方法和屬性。
十一挺邀、文件讀寫
文件讀寫通常通過 savetxt揉忘、loadtxt 等 I/O 函數(shù)來實現(xiàn):
>>> np.savetxt('m2.txt',m2) # 將上面定義的 m2 對象作為 m2.txt 存儲在當(dāng)前文件夾中
loadtxt 函數(shù)主要用來讀取 csv 格式的文件,自動切分字段,并將數(shù)據(jù)載入 numpy 數(shù)組:
>>> m2_reload=np.loadtxt('m2.txt',delimiter=' ') # delimiter 指定讀取文本的分隔符
>>> m2_reload
array([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
這里我來嘗試讀一個 excel 文件,文件名為1.xlsx 洞拨,內(nèi)容如下:
需要將其讀入 numpy 中作為一個數(shù)組對象:
>>> stock=np.dtype([('name',np.str_,4),('num',np.int32),('content',np.str_,20)])
>>> l_stock=np.loadtxt('C:\Users\EPAY\Desktop\\1.xlsx',delimiter=',',dtype=stock)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\numpy\lib\npyio.py", line 1044, in loadtxt
first_line = next(fh)
UnicodeDecodeError: 'gbk' codec can't decode bytes in position 22-23: illegal multibyte sequence
好了畸肆,理論上來說應(yīng)該是可以讀進(jìn)去的,但是可能由于我 excel 的編碼問題,導(dǎo)致讀進(jìn)去出現(xiàn)異常,參考了這個文檔童本,暫時還未解決:
https://stackoverflow.com/questions/24694736/numpy-loadtxt-encoding
歡迎讀者幫忙解決此類問題哗总,這里附上 excel 源文件:百度網(wǎng)盤
本文參考文檔:
http://old.sebug.net/paper/books/scipydoc/numpy_intro.html#ufunc
https://www.cnblogs.com/woaielf/p/5556553.html
梅西鎮(zhèn)樓~~~