Python中使用NumPy進(jìn)行數(shù)據(jù)處理方式
Numpy是一個(gè)常用的Python科學(xué)技術(shù)庫(kù),通過(guò)它可以快速對(duì)數(shù)組進(jìn)行操作,包括形狀操作、排序、選擇、輸入輸出、離散傅立葉變換、基本線性代數(shù),基本統(tǒng)計(jì)運(yùn)算和隨機(jī)模擬等。許多Python庫(kù)和科學(xué)計(jì)算的軟件包都使用Numpy數(shù)組作為操作對(duì)象,或者將傳入的Python數(shù)組轉(zhuǎn)化為Numpy數(shù)組,因此在Python中操作數(shù)據(jù)離不開(kāi)Numpy。
Numpy的核心是ndarray
對(duì)象,由Python的n維數(shù)組封裝而來(lái),但通過(guò)C語(yǔ)言預(yù)編譯相關(guān)的數(shù)組操作,因此比原生Python具有更高的執(zhí)行效率,但仍然使用Python語(yǔ)言編碼,這樣就同時(shí)具有簡(jiǎn)潔的代碼和高效的運(yùn)行速度。ndarry與數(shù)組有些區(qū)別值得注意,numpy數(shù)組中的元素都具有相同的類(lèi)型,并且在創(chuàng)建時(shí)就確定了固定的大小,這與Python數(shù)組對(duì)象可以動(dòng)態(tài)增長(zhǎng)不同。
1、數(shù)組屬性
Numpy對(duì)象的形式是同構(gòu)多維數(shù)組,數(shù)組的維度稱為軸(axis),每個(gè)維度上元素的個(gè)數(shù)稱為軸的長(zhǎng)度。例如下面是一個(gè)2×3的二維數(shù)組arr,第一軸長(zhǎng)度為3,第二軸長(zhǎng)度為2
arr = [[ 1., 0., 0.], [ 0., 1., 2.]]
arr數(shù)組對(duì)象常用的屬性如下:
# 數(shù)組軸的個(gè)數(shù) arr.ndim # 數(shù)組維度及長(zhǎng)度,例如2×3的數(shù)組其shape為(2, 3) arr.shape # 數(shù)組元素的總個(gè)數(shù) arr.size # 數(shù)組中元素的數(shù)據(jù)類(lèi)型 arr.dtype # 數(shù)組中元素所占字節(jié)數(shù) arr.itemsize
2、創(chuàng)建數(shù)組
可以通過(guò)array()
方法包裹普通python數(shù)組將其轉(zhuǎn)化為numpy數(shù)組,通過(guò)dtype=
規(guī)定元素的數(shù)據(jù)類(lèi)型。數(shù)組可以是二維等高維數(shù)組,也可以是元組的形式。
填充指定大小的數(shù)組可以使用函數(shù)zeros()
,將元素都填充為0,或者ones()
將元素填充為1,empty()
將元素填充為隨機(jī)數(shù)
np.random
模塊用于產(chǎn)生隨機(jī)數(shù),rand()
創(chuàng)建[0,1)內(nèi)指定維度的隨機(jī)數(shù)組,uniform()
、randint()
在指定范圍內(nèi)生成浮點(diǎn)數(shù)/整數(shù)。有時(shí)候我們希望產(chǎn)生的相同的隨機(jī)數(shù),或者產(chǎn)生的隨機(jī)數(shù)可以再現(xiàn),可以通過(guò)np.random.seed()
指定隨機(jī)數(shù)種子,當(dāng)種子相同時(shí)產(chǎn)生的隨機(jī)數(shù)相同。
arange(a,b,c)
函數(shù)用于從a到b每隔c長(zhǎng)度生成一個(gè)數(shù)組元素。linspace(a,b,c)
函數(shù)用于在a到b之間生成c個(gè)數(shù)組元素
import numpy as np # 普通數(shù)組轉(zhuǎn)化為numpy數(shù)組 a1 = np.array([2, 3, 4], dtype=float) print(a1) # 將元組數(shù)組轉(zhuǎn)化為二維numpy數(shù)組 a2 = np.array([(1, 2, 3), (3, 4, 5)]) print(a2) # 將3×3的數(shù)組用1填充 a3 = np.ones((3, 3)) print(a3) # 從1到10,每隔2生成一個(gè)元素 a4 = np.arange(1, 10, 2) print(a4) # 在1到12之間生成4個(gè)元素 a5 = np.linspace(1, 12, 4, dtype=int) print(a5) # 生成指定維度的隨機(jī)數(shù)組 print(np.random.rand(1, 5)) # 在指定區(qū)間生成隨機(jī)浮點(diǎn)數(shù) print(np.random.uniform(low=1, high=2, size=5)) # 在指定區(qū)間生成隨機(jī)浮點(diǎn)數(shù) print(np.random.randint(low=1, high=10, size=5)) # 使用相同的種子產(chǎn)生隨機(jī)數(shù) np.random.seed(666) print(np.random.rand(5)) np.random.seed(666) # 每次產(chǎn)生前都要設(shè)置 print(np.random.rand(5)) ''' 普通數(shù)組轉(zhuǎn)化為numpy對(duì)象: [2. 3. 4.] 元組數(shù)組: [[1 2 3] [3 4 5]] 用1填充數(shù)組: [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]] 從1到10每隔2生成一個(gè)元素: [1 3 5 7 9] 在1到12之間生成4個(gè)元素: [ 1 4 8 12] 生成(1, 5)浮點(diǎn)數(shù)組 [[0.73483009 0.42395071 0.03067476 0.87905934 0.3825438 ]] 在[1,2)產(chǎn)生5個(gè)隨機(jī)浮點(diǎn)數(shù)數(shù) [1.73563967 1.20877954 1.59162307 1.1021683 1.29736842] 在[1,10)產(chǎn)生5個(gè)隨機(jī)整數(shù) [6 5 3 6 8] 相同的隨機(jī)數(shù) [0.70043712 0.84418664 0.67651434 0.72785806 0.95145796] [0.70043712 0.84418664 0.67651434 0.72785806 0.95145796] '''
3、數(shù)組操作
3.1 數(shù)組運(yùn)算
算術(shù)運(yùn)算符可以直接運(yùn)用在矩陣上,其結(jié)果是將運(yùn)算應(yīng)用到每個(gè)元素上,例如矩陣A*B就是每個(gè)元素對(duì)應(yīng)相乘,矩陣的乘法運(yùn)算使用的是@符號(hào)
A = np.array([[1, 1], [0, 1]]) B = np.array([[2, 0], [3, 4]]) print(A * B) print(A @ B) ''' 矩陣元素對(duì)應(yīng)相乘: [[2 0] [0 4]] 矩陣的乘法: [[5 4] [3 4]] '''
numpy中有些函數(shù)應(yīng)用于整個(gè)數(shù)組,例如求和sum
、最大值max
、最小值min
。如果在這些參數(shù)中指定了某個(gè)軸,則應(yīng)用于指定軸。
還有一些函數(shù)應(yīng)用于數(shù)組中的具體元素,例如求sin
、cos
、exp
、開(kāi)方sqrt
等,這些函數(shù)叫做通函數(shù)(ufunc)
a = np.array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]) print(a.max()) # 求整體的最大值,結(jié)果為11 print(a.sum(axis=0)) # 求每一列的和,結(jié)果為:[12 15 18 21] print(np.sqrt(a)) # 數(shù)組每個(gè)元素求開(kāi)方
3.2 選取元素
numpy中的數(shù)組同python中的list一樣可以進(jìn)行索引、切片和迭代操作。a[x]
代表訪問(wèn)數(shù)組a下標(biāo)為x的元素,a[x:y]
代表訪問(wèn)數(shù)組從x到y(tǒng)的元素,如果省略x代表從頭開(kāi)始,省略y代表直到結(jié)尾。a[x:y:a]
代表從x到y(tǒng)每隔a個(gè)元素取一個(gè)值,如果a為負(fù)數(shù),代表逆序取值。
a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) print(a[1:3]) # 輸出下標(biāo)為1到3的元素:[1 2] print(a[::-2]) # 逆序每隔兩個(gè)元素選一個(gè)值:[9 7 5 3 1]
如果是多維數(shù)組,則索引之間用逗號(hào)分隔。可以使用…代表省略某幾個(gè)維度,如果省略則會(huì)被認(rèn)為是該維度全部輸出,例如x[...,3]
等效于 x[:,:,:,:,3]。
可以通過(guò)for
循環(huán)迭代多為數(shù)組,其內(nèi)容為低一維度的子數(shù)組,如果希望遍歷每一個(gè)子元素,可以使用flat
屬性。
a = np.array([[0, 1, 2, 3], [10, 11, 12, 13], [40, 41, 42, 43]]) # 輸出a第一維(行)的前三個(gè),第二維(列)下標(biāo)的1~3 print(a[1:3, 0:3]) # 輸出行的所有,下標(biāo)為2的列 print(a[2, ...]) # 遍歷數(shù)組 for row in a: print(row) # 遍歷每個(gè)子元素 for item in a.flat: print(item) ''' 后兩行的1~3列: [[10 11 12] [40 41 42]] 第三行的所有列: [40 41 42 43] 遍歷數(shù)組: [0 1 2 3] [10 11 12 13] [40 41 42 43] 遍歷每個(gè)元素: 0 1 2 ...... 41 42 43 '''
除了使用具體數(shù)字作為索引,還可以使用numpy數(shù)組作為索引。例如當(dāng)索引i為多維數(shù)組時(shí),將會(huì)按照i的位置從數(shù)組a中取出元素
a = np.arange(12) ** 2 print(a) i = np.array([1, 3, 5]) print(a[i]) # 多維數(shù)組索引j j = np.array([[3, 4], [9, 7]]) print(a[j]) ''' [ 0 1 4 9 16 25 36 49 64 81 100 121] 數(shù)組a的1、3、5個(gè)元素 [ 1 9 25] 通過(guò)多為索引j取出a的數(shù)據(jù)填到對(duì)應(yīng)位置 [[ 9 16] [81 49]] '''
當(dāng)索引數(shù)組由單個(gè)元素組成時(shí),默認(rèn)對(duì)數(shù)組a的第一個(gè)維度進(jìn)行選擇。若需要對(duì)數(shù)組在多個(gè)維度上進(jìn)行索引,則傳入多個(gè)索引組成的數(shù)組i,j并用逗號(hào)分隔
a = np.array(([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]])) # 對(duì)a的第一個(gè)維度進(jìn)行選擇 i = np.array([0, 1]) print(a[i]) # 對(duì)數(shù)組a在多個(gè)維度上進(jìn)行選擇,同時(shí)提供i,j代表取出a的[0,2]、[1,3]兩個(gè)元素 j = np.array([2, 3]) print(a[i, j]) ''' 選擇多維數(shù)組a的第0、1兩行: [[0 1 2 3] [4 5 6 7]] a的[0,2]、[1,3]兩個(gè)元素: [2 7] '''
還可以通過(guò)True/False數(shù)組代表元素是否被選中,例如下面有一個(gè)True/False數(shù)組mask,新建一個(gè)全為0的2×2數(shù)組padded,然后使用一個(gè)數(shù)組序列[1,2,3]去填充padded,可見(jiàn)mask為T(mén)rue的地方被選擇并填充,F(xiàn)alse的地方未被選中,仍為0.
mask = np.array([[True, False], [True, True]]) padded = np.zeros((2, 2)) padded[mask] = np.array([1, 2, 3]) # 用序列填充被mask選中的位置 print(padded) ''' [[1. 0.] [2. 3.]] '''
3.3 改變維度
數(shù)組的reshape()
方法可以將原數(shù)組重構(gòu)成目標(biāo)維度的數(shù)組,例如將一個(gè)2×6的數(shù)組重構(gòu)為3×4的數(shù)組,
數(shù)組在重構(gòu)時(shí)不會(huì)修改原數(shù)組,而是返回修改后的結(jié)果數(shù)組
值得注意的是數(shù)組在重構(gòu)和打印時(shí)都是從最右邊的維度開(kāi)始往左進(jìn)行,例如下面的3×4的數(shù)組b,先按行排列4個(gè),然后再換行,排列這樣的3行。如果是多維,則按這樣的行列繼續(xù)輸出。如果數(shù)組維度為-1,則會(huì)自動(dòng)計(jì)算該維度的大小,例如含有12個(gè)元素的數(shù)組,第二、第三維是3×2,則第一維就是2
ravel()
函數(shù)可以將數(shù)組展成一維數(shù)組。
a=np.array([[1,2,3,4,5,6], [7,8,9,10,11,12]]) b=a.reshape(3,4) print(b) # 多維數(shù)組,自動(dòng)計(jì)算 print(a.reshape(-1,3,2)) # 展開(kāi)數(shù)組 flatted = b.ravel() print(flatted, end=' ') ''' [[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]] 2×3×2的多維數(shù)組: [[[ 1 2] [ 3 4] [ 5 6]] [[ 7 8] [ 9 10] [11 12]]] 展開(kāi)數(shù)組: [ 1 2 3 4 5 6 7 8 9 10 11 12] '''
transpose()
函數(shù)可以實(shí)現(xiàn)數(shù)組轉(zhuǎn)置的功能,例如下面數(shù)組a為一個(gè)4×3×2的三維數(shù)組,通過(guò)transpose(2,0,1),其中的0、1、2分別代表數(shù)組原來(lái)的維度第一、二、三維,在括號(hào)中的位置代表轉(zhuǎn)置后的維度,因此結(jié)果將數(shù)組的第三維放到第一維,第一維放到第二維,第二維放到第三維,即轉(zhuǎn)置為3×2×4的數(shù)組。
a = np.array([ [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]] ]) b = a.transpose(2, 0, 1) print(b) ''' [[[ 1 5 9] [13 17 21]] [[ 2 6 10] [14 18 22]] [[ 3 7 11] [15 19 23]] [[ 4 8 12] [16 20 24]]] '''
3.4 數(shù)組的合并
numpy的concatenate()
可以用于數(shù)組的合并,其第一個(gè)參數(shù)為要合并的數(shù)組,放在一個(gè)tuple()或list[]中。第二個(gè)參數(shù)axis
指定合并的軸,默認(rèn)axis=0,即從第一維合并所有子元素
a1 = np.array([[1, 3], [5, 7]]) a2 = np.array([[2, 4], [6, 8]]) a3 = np.concatenate((a1, a2)) # 合并數(shù)組 print(a3) print(np.concatenate((a1, a2), axis=1)) # 指定合并的軸 ''' [[1 3] [5 7] [2 4] [6 8]] [[1 3 2 4] [5 7 6 8]] '''
numpy的hstack()
函數(shù)可以在水平方向上合并多個(gè)數(shù)組,vstack()
函數(shù)可以在垂直方向上合并多個(gè)數(shù)組
相反地,hsplit()
、vsplit()
可以拆分為指定數(shù)量的數(shù)組
a=np.array([1,2,3]) b=np.array([4,5,6]) # 垂直方向合并 c=np.vstack((a,b)) print(c) # 水平方向合并 print(np.hstack((a,b))) # 水平方向拆分 print(np.hsplit(c,3)) ''' 垂直堆疊 [[1 2 3] [4 5 6]] 水平合并 [1 2 3 4 5 6] 水平拆分為三個(gè)1×2的: [array([[1], [4]]), array([[2], [5]]), array([[3], [6]])] '''
3.5 數(shù)組的復(fù)制
當(dāng)一個(gè)數(shù)組對(duì)象賦值給一個(gè)新的變量時(shí),是新開(kāi)辟一個(gè)存儲(chǔ)空間還是只是傳遞一個(gè)引用?答案是引用。
例如執(zhí)行語(yǔ)句b=a,只是將一個(gè)引用傳給了b,對(duì)b執(zhí)行的操作會(huì)直接影響a。查看a、b兩個(gè)對(duì)象的節(jié)點(diǎn)id也是一樣的
a = np.array([1, 2, 3]) b = a # 修改b b[0] = 0 print(a) # 輸出a、b對(duì)象的id print(id(a), id(b)) ''' 修改b,a也發(fā)生了變化 [0 2 3] 查看二者的id 2290013812656 2290013812656 '''
通過(guò)切片返回?cái)?shù)組的視圖,修改視圖的形狀不會(huì)影響原數(shù)組,但是在視圖上修改數(shù)據(jù)原數(shù)組也會(huì)改變。在執(zhí)行del a之后,由于c引用了a,a依舊會(huì)存在內(nèi)存中不會(huì)被刪除
c = a[:] # 修改視圖的形狀 c.shape = 3, 1 print(c, a) # 修改視圖c的數(shù)據(jù) c[0] = 1 print(a[0]) ''' 對(duì)視圖c的形狀做修改,a不會(huì)受到影響 [[0] [2] [3]] [0 2 3] 修改c的數(shù)據(jù),a也會(huì)隨之改變: 1 '''
通過(guò)copy()
方法可以生成數(shù)據(jù)的副本,對(duì)副本的操作完全不會(huì)影響原數(shù)組
d= a.copy() d[0]=5 # 修改數(shù)組的副本d,a不受影響,輸出a:[1 2 3] print(a)
4、保存文件
numpy通過(guò)save()
將一個(gè)數(shù)組arr保存為.npy文件,并且可以通過(guò)np.load()
讀取該文件
如果npy文件中存在序列化的pickled對(duì)象,則需要設(shè)置屬性allow_pickle=True
,否則會(huì)報(bào)錯(cuò)
ValueError: Object arrays cannot be loaded when allow_pickle=False
np.save("output.npy",arr) arr = np.load("output.npy", allow_pickle=True)
如果需要儲(chǔ)存多個(gè)數(shù)組,可以通過(guò)np.savez()
保存為.npz文件,其變量名作為數(shù)組的key值,同理可以使用load()
讀取
np.savez('array_save.npz',arr1,arr2,arr3) Arr=np.load('arr_save.npz') arr1=Arr['arr1'] # 通過(guò)key值取到不同數(shù)組
.npy與.npz文件無(wú)法手動(dòng)查看,如果需要查看可以保存為txt文本的格式,通過(guò)savetxt()
保存,并通過(guò)loadtxt()
讀取
np.savetxt('data.txt',arr) data=np.loadtxt('data.txt')
在保存文件時(shí)可以通過(guò)fmt
屬性設(shè)置輸出數(shù)組的格式,如下設(shè)置保存數(shù)據(jù)為整型,且后跟一個(gè)制表符
np.savetxt("./output.txt", data, fmt='%d')
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用Django和Flask獲取訪問(wèn)來(lái)源referrer
這篇文章主要介紹了使用Django和Flask獲取訪問(wèn)來(lái)源referrer,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04詳解python 破解網(wǎng)站反爬蟲(chóng)的兩種簡(jiǎn)單方法
這篇文章主要介紹了詳解python 破解網(wǎng)站反爬蟲(chóng)的兩種簡(jiǎn)單方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02python實(shí)現(xiàn)釘釘機(jī)器人自動(dòng)打卡天天早下班
這篇文章主要為大家介紹了python實(shí)現(xiàn)釘釘機(jī)器人自動(dòng)打卡天天下早班實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06python數(shù)字圖像處理實(shí)現(xiàn)直方圖與均衡化
在圖像處理中,直方圖是非常重要,也是非常有用的一個(gè)處理要素。這篇文章主要介紹了python數(shù)字圖像處理實(shí)現(xiàn)直方圖與均衡化,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05淺談Python3中strip()、lstrip()、rstrip()用法詳解
這篇文章主要介紹了淺談Python3中strip()、lstrip()、rstrip()用法詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04Python自定義主從分布式架構(gòu)實(shí)例分析
這篇文章主要介紹了Python自定義主從分布式架構(gòu),結(jié)合實(shí)例形式分析了主從分布式架構(gòu)的結(jié)構(gòu)、原理與具體的代碼實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-09-09