重磅干貨,,第一時(shí)間送達(dá) Numpy是數(shù)據(jù)分析和科學(xué)計(jì)算的核心包,,上文詳細(xì)介紹了Numpy的入門教程,本文將詳細(xì)介紹Numpy的高級(jí)特性,,這些特性對(duì)于數(shù)據(jù)分析和處理非常重要,。 1. 如何獲取滿足條設(shè)定件的索引 2. 如何將數(shù)據(jù)導(dǎo)入和導(dǎo)出csv文件 3. 如何保存和加載numpy對(duì)象 4. 如何按列或行拼接numpy數(shù)組 5. 如何按列對(duì)numpy數(shù)組進(jìn)行排序 6. 如何用numpy處理日期 7.高階numpy函數(shù)介紹 8. 小結(jié) 上一文介紹根據(jù)數(shù)組是否滿足條件,輸出為True或False. # 定義數(shù)組 若我們想得到滿足條件的索引,用np.where函數(shù)實(shí)現(xiàn). # 定位數(shù)組大于5的索引 index_gt5 = np.where(arr_rand > 5) print('Positions where value > 5: ', index_gt5) #> Positions where value > 5: (array([0, 1, 3, 4]),) # 索引 由索引得到滿足條件的值. # 根據(jù)索引得到滿足條件的數(shù)組值 np.where也可以接受另兩個(gè)可選擇的參數(shù)x和y,。當(dāng)條件滿足時(shí),輸出x,,反之輸出y. # 如果值大于5,,輸出字符串'gt5',反之輸出'le5' np.where(arr_rand > 5, 'gt5', 'le5') #> array(['gt5', 'gt5', 'le5', 'gt5', 'gt5', 'le5', 'le5', 'le5', 'le5', 'le5'], dtype='<U3') np.argmax和np.argmin分別獲取數(shù)組最大值和最小值的索引. # 最大值索引 np.max和np.min分別獲取數(shù)組的最大值和最小值. # 最大值 print('max value: ', np.max(arr_rand)) # 最小值 print('min value: ', np.min(arr_rand)) #> max value: 8 #> min value: 0 導(dǎo)入數(shù)據(jù)的標(biāo)準(zhǔn)方法是使用np.genfromtxt函數(shù),,它可以從web URLs導(dǎo)入數(shù)據(jù),,處理缺失值,多種分隔符,,處理不規(guī)則的列數(shù)等功能,。一個(gè)不太通用的版本是用np.loadtxt函數(shù)導(dǎo)入數(shù)據(jù),它假設(shè)數(shù)據(jù)集無(wú)缺失值. 作為示例,,我們嘗試從下面的URL讀取.csv文件,,由于numpy數(shù)組的所有元素都應(yīng)該是同一種類型,因此文本的最后一列默認(rèn)為'nan',。通過(guò)設(shè)置參數(shù)'filling_values',,你可以用其他值代替缺失值. # 關(guān)閉數(shù)字的科學(xué)表示方法 若設(shè)置參數(shù)dtype為'object'或'None',,np.genfromtxt在未設(shè)置占位符的前提下能同時(shí)處理具有數(shù)字和文本列的數(shù)據(jù)集. # data2 = np.genfromtxt(path, delimiter=',', skip_header=1, dtype='object') data2 = np.genfromtxt(path, delimiter=',', skip_header=1, dtype=None) data2[:3] # 顯示前三行 #> array([( 18., 8, 307., 130, 3504, 12. , 70, 1, b''chevrolet chevelle malibu''), #> ( 15., 8, 350., 165, 3693, 11.5, 70, 1, b''buick skylark 320''), #> ( 18., 8, 318., 150, 3436, 11. , 70, 1, b''plymouth satellite'')], #> dtype=[('f0', '<f8'), ('f1', '<i8'), ('f2', '<f8'), ('f3', '<i8'), ('f4', '<i8'), ('f5', '<f8'), ('f6', '<i8'), ('f7', '<i8'), ('f8', 'S38')]) 最后,,'np.savetxt'將數(shù)據(jù)保存為csv文件. # 保存數(shù)據(jù)為csv文件 Numpy提供了.npy和.npz文件類型來(lái)實(shí)現(xiàn)。如果保存一個(gè)ndarray數(shù)據(jù),,使用np.save保存為.npy文件,;若保存多個(gè)ndarray數(shù)據(jù),使用np.savez保存為.npz文件,。加載numpy數(shù)據(jù),,則統(tǒng)一用np.load函數(shù). # 保存單一的numpy數(shù)據(jù),使用.npy文件 np.save('myarray.npy', arr2d) # 保存多個(gè)numpy數(shù)據(jù),,使用.npz文件 np.savez('array.npz', arr2d_f, arr2d_b) # 加載.npy文件 a = np.load('myarray.npy') print(a) #> [[0 1 2] #> [3 4 5] #> [6 7 8]] 加載.npz文件,,獲取特定的數(shù)組值. # 加載.npz文件 雖然通過(guò)'arr_0'和'arr_1'獲取了數(shù)組值,但是我們對(duì)這兩個(gè)索引比較陌生,,下面介紹手動(dòng)設(shè)置索引保存和加載數(shù)組. # 增加索引保存數(shù)據(jù) b=np.savez('array.npz',arr2d_f=arr2d_f,arr2d_b=arr2d_b) c = np.load('array.npz') print(c.files) c['arr2d_f'] #> ['arr2d_f', 'arr2d_b'] #> array([[1., 2., 3., 4.], [3., 4., 5., 6.], [5., 6., 7., 8.]]) 本節(jié)介紹三種拼接numpy數(shù)組的方法:
需要注意的是,np.r_和np.c_使用方括號(hào)來(lái)拼接數(shù)組,,其他兩種方法使用括號(hào)。 首先,,定義兩個(gè)需要拼接的數(shù)組. # 定義兩個(gè)拼接的數(shù)組 行拼接數(shù)組 # 行拼接數(shù)組 np.concatenate([a, b], axis=0) np.vstack([a,b]) np.r_[a,b] #> array([[ 0., 0., 0., 0.], #> [ 0., 0., 0., 0.], #> [ 0., 0., 0., 0.], #> [ 0., 0., 0., 0.], #> [ 1., 1., 1., 1.], #> [ 1., 1., 1., 1.], #> [ 1., 1., 1., 1.], #> [ 1., 1., 1., 1.]]) 列拼接數(shù)組 # 列拼接 本節(jié)介紹三種按列排序方法:np.sort,,np.argsort和np.lexsort。在介紹三種排序方法前,,先定義一個(gè)2維數(shù)組. arr = np.random.randint(1,6, size=[8, 4]) arr #> array([[3, 3, 2, 1], #> [1, 5, 4, 5], #> [3, 1, 4, 2], #> [3, 4, 5, 5], #> [2, 4, 5, 5], #> [4, 4, 4, 2], #> [2, 4, 1, 3], #> [2, 2, 4, 3]]) np.sort基于列對(duì)arr數(shù)組進(jìn)行排序. # axis=0表示列排序,,1表示行排序 由上面結(jié)果分析,np.sort排序函數(shù)認(rèn)為所有列是相互獨(dú)立的,,對(duì)所有列進(jìn)行排序,,破壞了每行的結(jié)構(gòu), 使用np.argsort函數(shù)可以保留行的完整性 . # 對(duì)arr的第一列進(jìn)行排序,,返回索引 sorted_index_1stcol = arr[:, 0].argsort() # 根據(jù)第一列的索引對(duì)數(shù)組排序,,保留了行的完整性 arr[sorted_index_1stcol] #> array([[1, 5, 4, 5], #> [2, 4, 5, 5], #> [2, 4, 1, 3], #> [2, 2, 4, 3], #> [3, 3, 2, 1], #> [3, 1, 4, 2], #> [3, 4, 5, 5], #> [4, 4, 4, 2]]) 倒轉(zhuǎn)argsort索引實(shí)現(xiàn)遞減排序 # 遞減排序 若要基于多個(gè)列對(duì)數(shù)組進(jìn)行排序,使用np.lexsort函數(shù),,它的參數(shù)是元組類型,,元組的每個(gè)元素表示數(shù)組的某一列,排序規(guī)則是:越靠近右邊的列,,優(yōu)先級(jí)越高. # 先比較第一列,,第一列相同的情況下再比較第二列 lexsorted_index = np.lexsort((arr[:, 1], arr[:, 0])) arr[lexsorted_index] #> array([[1, 5, 4, 5], #> [2, 2, 4, 3], #> [2, 4, 5, 5], #> [2, 4, 1, 3], #> [3, 1, 4, 2], #> [3, 3, 2, 1], #> [3, 4, 5, 5], #> [4, 4, 4, 2]]) np.datatime64創(chuàng)建日期對(duì)象,精確度達(dá)到納秒,,你可以使用標(biāo)準(zhǔn)的YYYY-MM-DD格格式的字符串作為參數(shù)創(chuàng)建日期. # 創(chuàng)建datetime64對(duì)象 從datatime64對(duì)象分離時(shí)間 # 從datatime64對(duì)象分離時(shí)間 dt64 = np.datetime64(date64, 'D') dt64 #> numpy.datetime64('2018-02-04') 如果你想增加天數(shù)或其他任何時(shí)間單元,,比如月份,小時(shí),,秒等,,使用np.timedelta函數(shù)非常方便. # np.delta建立多個(gè)時(shí)間單元 dt64對(duì)象轉(zhuǎn)化為字符串 # dt64轉(zhuǎn)化為字符串 np.datetime_as_string(dt64) #> '2018-02-04' np.is_busday函數(shù)判斷日期是否為工作日,工作日默認(rèn)為周一至周五. print('Date: ', dt64) 手動(dòng)設(shè)置工作日的時(shí)間,,如設(shè)置工作日為周六周日,,其他時(shí)間為休息日. date64 = np.datetime64('2019-04-14') # 設(shè)置周六周日為工作日 np.is_busday(date64,weekmask='Sat Sun') #> True np.busday_offset查看后幾個(gè)工作日的日期. # 周四 若當(dāng)前工作日為非工作日,則默認(rèn)是報(bào)錯(cuò)的. # 周六 date64 = np.datetime64('2019-04-13') # 查看兩個(gè)工作日后的日期 t = np.busday_offset(date64, 2) t #> ValueError: Non-business day date in busday_offset # 非工作日不能作為busday_offset的參數(shù) 可以增加參數(shù)forward或backward來(lái)報(bào)錯(cuò),,forward的含義是若當(dāng)前日期非工作日,,那么往前尋找最接近當(dāng)前日期的工作日,backward的含義則是往后尋找最接近當(dāng)前日期的工作日. #當(dāng)前時(shí)間為周六(2019-04-13),,往前最接近當(dāng)前時(shí)間的工作日是2019-04-15,,兩個(gè)工作日偏移后的日期是2019-04-17 6.1 如何創(chuàng)建日期序列 np.arange可簡(jiǎn)單創(chuàng)建日期序列 # 建立日期序列 dates = np.arange(np.datetime64('2018-02-01'), np.datetime64('2018-02-10')) print(dates) # 檢查是否為工作日 np.is_busday(dates) #> ['2018-02-01' '2018-02-02' '2018-02-03' '2018-02-04' '2018-02-05' #> '2018-02-06' '2018-02-07' '2018-02-08' '2018-02-09'] array([ True, True, False, False, True, True, True, True, True], dtype=bool) 6.2 如何把numpy.data64對(duì)象轉(zhuǎn)化為datatime.datatime對(duì)象 # np.datetime64類型轉(zhuǎn)化為datetime.datetime類型 獲取datatime對(duì)象的年月日非常簡(jiǎn)便 print('Year: ', dt.year) print('Day of month: ', dt.day) print('Month of year: ', dt.month) print('Day of Week: ', dt.weekday()) # 周五 #> Year: 2018 #> Day of month: 4 #> Month of year: 2 #> Day of Week: 6 7.1 標(biāo)量函數(shù)的向量化 標(biāo)量函數(shù)只能處理標(biāo)量,,不能處理數(shù)組 # 定義標(biāo)量函數(shù) np.vectorize使標(biāo)量函數(shù)也能處理數(shù)組,,可選參數(shù)otypes為輸出的類型. # 函數(shù)向量化,向量化的輸出類型是float foo_v = np.vectorize(foo, otypes=[float]) print('x = [10, 11, 12] returns ', foo_v([10, 11, 12])) print('x = [[10, 11, 12], [1, 2, 3]] returns ', foo_v([[10, 11, 12], [1, 2, 3]])) #> x = [10, 11, 12] returns [ 5. 121. 6.] #> x = [[10, 11, 12], [1, 2, 3]] returns [[ 5. 121. 6.] #> [ 1. 1. 9.]] 7.2 apply_along_axis函數(shù) 首先定義一個(gè)二維數(shù)組 # 定義一個(gè)4x10的隨機(jī)二維數(shù)組 如果我們要找數(shù)組每行或每列的最大值,,numpy的一個(gè)最大特點(diǎn)是基于向量化操作的,,因此我們使用np.apply_along_axis函數(shù)找每行或每列的最大值. # 基于列操作,找每列的最大值 print('max of per column: ', np.apply_along_axis(np.max, 0, arr=arr_x)) # 基于行操作,,找每行的最大值 print('max of per row: ', np.apply_along_axis(np.max, 1, arr=arr_x)) #> max of per column: [9 9 4 8 9 6 9 7 6 8] #> max of per row: [9 9 8 9] 7.3 searchsorted函數(shù) np.searchsorted函數(shù)返回某一變量在有序數(shù)組的位置,,在該位置插入變量后數(shù)組仍然是有序的. # 生成有序數(shù)組 7.4 如何增加數(shù)組維度 在不增加任何額外數(shù)據(jù)的前提下,,np.newaxis函數(shù)可以增加數(shù)組的維數(shù),,newaxis在的位置就是要增加的維度. # 定義一維數(shù)組 x = np.arange(5) print('Original array: ', x) # 數(shù)組維度為2 print('ndims of x:', x.ndim) # 列維度增加 x_col = x[:, np.newaxis] print(x_col) # 數(shù)組維度為2 print('ndims of x_col: ', x_col.ndim) print('x_col shape: ', x_col.shape) # 行維度增加 x_row = x[np.newaxis, :] print(x_row) print('x_row shape: ', x_row.shape) # 數(shù)組維度為2 print('ndims of x_row: ', x_row.ndim) #> Original array: [0 1 2 3 4] #> ndims of x: 1 #> [[0] [1] [2] [3] [4]] #> ndims of x_col: 2 #> x_col shape: (5, 1) #> [[0 1 2 3 4]] #> x_row shape: (1, 5) #> ndims of x_row: 2 7.5 Digitize函數(shù) np.digitize函數(shù)返回?cái)?shù)組每個(gè)元素屬于bin的索引位置. # 構(gòu)建數(shù)組和bin 可視化分析digitize算法原理: 如上圖,根據(jù)變量落在bin的區(qū)間范圍,,返回對(duì)應(yīng)的索引. 7.7 Clip函數(shù) np.clip函數(shù)將數(shù)字限制在給定截止范圍內(nèi),,所有小于范圍下限的數(shù)被當(dāng)成下限值,大于范圍上限的數(shù)被當(dāng)成上限值. # 限制x的所有元素位于3和8之間 np.clip(x, 3, 8) #> array([3, 3, 3, 3, 4, 5, 6, 7, 8, 8]) 7.8 Histogram函數(shù)和Bincount函數(shù) np.bincount函數(shù)統(tǒng)計(jì)最小值到最大值的個(gè)數(shù),,最小值為0. # Bincount例子 np.histogram函數(shù)統(tǒng)計(jì)數(shù)據(jù)落入bins的區(qū)間,,不考慮bins兩側(cè)的區(qū)間(如下圖所示). x = np.array([1,1,2,3,2,4,4,5,6,6,6]) counts, bins = np.histogram(x, [0, 2, 4, 6, 8]) print('Counts: ', counts) print('Bins: ', bins) #> Counts: [2 3 3 3] #> Bins: [0 2 4 6 8] |
|