目錄python
1. 如何獲取知足條設定件的索引git
2. 如何將數據導入和導出csv文件github
3. 如何保存和加載numpy對象web
4. 如何按列或行拼接numpy數組算法
5. 如何按列對numpy數組進行排序數組
6. 如何用numpy處理日期app
7.高階numpy函數介紹dom
# 定義數組 import numpy as np arr_rand = np.array([8, 8, 3, 7, 7, 0, 4, 2, 5, 2]) #根據數組是否大於4,知足爲True,不知足爲False b = arr_rand > 4 b Out[3]: array([ True, True, False, True, True, False, False, False, True, False])
獲取知足條件的索引ide
# 定位數組大於5的索引 index_gt5 = np.where(arr_rand > 5) print("Positions where value > 5: ", index_gt5) Positions where value > 5: (array([0, 1, 3, 4], dtype=int64),)
由索引獲得知足條件的值.函數
# 根據索引獲得知足條件的數組值 arr_rand.take(index_gt5) Out[5]: array([[8, 8, 7, 7]])
np.where也能夠接受另兩個可選擇的參數x和y。當條件知足時,輸出x,反之輸出y.
# 若是值大於5,輸出字符串'gt5',反之輸出'le5' np.where(arr_rand > 5, 'gt5', 'le5') Out[6]: array(['gt5', 'gt5', 'le5', 'gt5', 'gt5', 'le5', 'le5', 'le5', 'le5', 'le5'], dtype='<U3')
np.argmax和np.argmin分別獲取數組最大值和最小值的索引.
# 最大值索引 print('Position of max value: ', np.argmax(arr_rand)) # 最小值索引 print('Position of min value: ', np.argmin(arr_rand)) Position of max value: 0 Position of min value: 5
np.max和np.min分別獲取數組的最大值和最小值.獲取最大最小值
# 最大值 print('max value: ', np.max(arr_rand)) # 最小值 print('min value: ', np.min(arr_rand)) max value: 8 min value: 0
導入數據的標準方法是使用np.genfromtxt函數,它能夠從web URLs導入數據,處理缺失值,多種分隔符,處理不規則的列數等功能。一個不太通用的版本是用np.loadtxt函數導入數據,它假設數據集完好失值.
做爲示例,咱們嘗試從下面的URL讀取.csv文件,因爲numpy數組的全部元素都應該是同一種類型,所以文本的最後一列默認爲'nan'。經過設置參數'filling_values',你能夠用其餘值代替缺失值.
# 關閉數字的科學表示方法 np.set_printoptions(suppress=True) # 從url的csv文件導入數據 path = 'https://raw.githubusercontent.com/selva86/datasets/master/Auto.csv' # delimiter:分隔符,skip_header:從多少行開始讀數據,以0開始,filling_values:缺失值表示,dtype:數據類型 data = np.genfromtxt(path, delimiter=',', skip_header=1, filling_values=-999, dtype='float') data[:3] # 顯示前3行數據 #> array([[ 18. , 8. , 307. , 130. , 3504. , 12. , 70. , #> 1. , -999. ], #> [ 15. , 8. , 350. , 165. , 3693. , 11.5, 70. , #> 1. , -999. ], #> [ 18. , 8. , 318. , 150. , 3436. , 11. , 70. , #> 1. , -999. ]])
若設置參數dtype爲'object'或'None',np.genfromtxt在未設置佔位符的前提下能同時處理具備數字和文本列的數據集.
# 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'將數據保存爲csv文件.
# 保存數據爲csv文件 np.savetxt("out.csv", data, delimiter=",")
Numpy提供了.npy和.npz文件類型來實現。若是保存一個ndarray數據,使用np.save保存爲.npy文件;若保存多個ndarray數據,使用np.savez保存爲.npz文件。加載numpy數據,則統一用np.load函數.
# 保存單一的numpy數據,使用.npy文件 np.save('myarray.npy', arr2d) # 保存多個numpy數據,使用.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文件,獲取特定的數組值.
# 加載.npz文件 b = np.load('array.npz') print(b.files) b['arr_0'] #> ['arr_0', 'arr_1'] #> array([[ 0., 1., 2.], #> [ 3., 4., 5.], #> [ 6., 7., 8.]])
雖然經過'arr_0'和'arr_1'獲取了數組值,可是咱們對這兩個索引比較陌生,下面介紹手動設置索引保存和加載數組.
# 增長索引保存數據 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.]])
本節介紹三種拼接numpy數組的方法:
方法1:設置np.concatenate參數axis的值爲1或0,實現數組的列拼接或行拼接。
方法2:np.vstack和np.hstack
方法3:np.r_和np.c_
須要注意的是,np.r_和np.c_使用方括號來拼接數組,其餘兩種方法使用括號。
首先,定義兩個須要拼接的數組.
# 定義兩個拼接的數組 a = np.zeros([4, 4]) b = np.ones([4, 4]) print(a) print(b) #> [[ 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.]]
行拼接數組
# 行拼接數組 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.]])
列拼接數組
# 列拼接 np.concatenate([a, b], axis=1) np.hstack([a,b]) np.c_[a,b] #> array([[ 0., 0., 0., 0., 1., 1., 1., 1.], #> [ 0., 0., 0., 0., 1., 1., 1., 1.], #> [ 0., 0., 0., 0., 1., 1., 1., 1.], #> [ 0., 0., 0., 0., 1., 1., 1., 1.]])
本節介紹三種按列排序方法:np.sort,np.argsort和np.lexsort。在介紹三種排序方法前,先定義一個2維數組.
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基於列對arr數組進行排序.
# axis=0表示列排序,1表示行排序 np.sort(arr, axis=0) #> array([[1, 1, 1, 1], #> [2, 2, 2, 2], #> [2, 3, 4, 2], #> [2, 4, 4, 3], #> [3, 4, 4, 3], #> [3, 4, 4, 5], #> [3, 4, 5, 5], #> [4, 5, 5, 5]])
由上面結果分析,np.sort排序函數認爲全部列是相互獨立的,對全部列進行排序,破壞了每行的結構,
使用np.argsort函數能夠保留行的完整性 .
# 對arr的第一列進行排序,返回索引 sorted_index_1stcol = arr[:, 0].argsort() # 根據第一列的索引對數組排序,保留了行的完整性 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]])
倒轉argsort索引實現遞減排序
# 遞減排序 arr[sorted_index_1stcol[::-1]] #> array([[4, 4, 4, 2], #> [3, 4, 5, 5], #> [3, 1, 4, 2], #> [3, 3, 2, 1], #> [2, 2, 4, 3], #> [2, 4, 1, 3], #> [2, 4, 5, 5], #> [1, 5, 4, 5]])
若要基於多個列對數組進行排序,使用np.lexsort函數,它的參數是元組類型,元組的每一個元素表示數組的某一列,排序規則是:越靠近右邊的列,優先級越高.
# 先比較第一列,第一列相同的狀況下再比較第二列 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建立日期對象,精確度達到納秒,你可使用標準的YYYY-MM-DD格格式的字符串做爲參數建立日期.
# 建立datetime64對象 date64 = np.datetime64('2018-02-04 23:10:10') date64 #> numpy.datetime64('2018-02-04T23:10:10')
從datatime64對象分離時間
# 從datatime64對象分離時間 dt64 = np.datetime64(date64, 'D') dt64 #> numpy.datetime64('2018-04-14')
若是你想增長天數或其餘任什麼時候間單元,好比月份,小時,秒等,使用np.timedelta函數很是方便.
# np.delta創建多個時間單元 tenminutes = np.timedelta64(10, 'm') # 10 分鐘 tenseconds = np.timedelta64(10, 's') # 10 秒鐘 tennanoseconds = np.timedelta64(10, 'ns') # 10 納秒 print('Add 10 days: ', dt64 + 10) # 增長10天 print('Add 10 minutes: ', dt64 + tenminutes) # 增長10分鐘 print('Add 10 seconds: ', dt64 + tenseconds) # 增長10秒 print('Add 10 nanoseconds: ', dt64 + tennanoseconds) # 增長10納秒 #> Add 10 days: 2018-02-14 #> Add 10 minutes: 2018-02-04T00:10 #> Add 10 seconds: 2018-02-04T00:00:10 #> Add 10 nanoseconds: 2018-02-04T00:00:00.000000010
dt64對象轉化爲字符串
# dt64轉化爲字符串 np.datetime_as_string(dt64) #> '2018-04-14'
np.is_busday函數判斷日期是否爲工做日,工做日默認爲週一至週五.
print('Date: ', dt64) print("Is it a business day?: ", np.is_busday(dt64)) #> Date: 2018-02-04 #> Is it a business day?: False # False表示不是
手動設置工做日的時間,如設置工做日爲週六週日,其餘時間爲休息日.
date64 = np.datetime64('2019-04-14') # 設置週六週日爲工做日 np.is_busday(date64,weekmask='Sat Sun') #> True
np.busday_offset查看後幾個工做日的日期.
# 週四 date64 = np.datetime64('2019-04-11') # 查看兩個工做往後的日期 t = np.busday_offset(date64, 2) t #> numpy.datetime64('2019-04-15')
若當前工做日爲非工做日,則默認是報錯的.
# 週六 date64 = np.datetime64('2019-04-13') # 查看兩個工做往後的日期 t = np.busday_offset(date64, 2) t #> ValueError: Non-business day date in busday_offset # 非工做日不能做爲busday_offset的參數
能夠增長參數forward或backward來報錯,forward的含義是若當前日期非工做日,那麼往前尋找最接近當前日期的工做日,backward的含義則是日後尋找最接近當前日期的工做日.
#當前時間爲週六(2019-04-13),往前最接近當前時間的工做日是2019-04-15,兩個工做日偏移後的日期是2019-04-17 print("Add 2 business days, rolling forward to nearest biz day: ", np.busday_offset(date64, 2, roll='forward')) #當前時間爲週六(2019-04-13),日後最接近當前時間的工做日是2019-04-12,兩個工做日偏移後的日期是2019-04-16 print("Add 2 business days, rolling backward to nearest biz day: ", np.busday_offset(date64, 2, roll='backward')) #> Add 2 business days, rolling forward to nearest biz day: 2019-04-17 #> Add 2 business days, rolling backward to nearest biz day: 2019-04-16
6.1 如何建立日期序列
np.arange可簡單建立日期序列
# 創建日期序列 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對象轉化爲datatime.datatime對象
# np.datetime64類型轉化爲datetime.datetime類型 import datetime dt = dt64.tolist() dt #> datetime.date(2018, 02, 10)
獲取datatime對象的年月日很是簡便
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 標量函數的向量化
標量函數只能處理標量,不能處理數組
# 定義標量函數 def foo(x): if x % 2 == 1: return x**2 else: return x/2 # On a scalar print('x = 10 returns ', foo(10)) print('x = 11 returns ', foo(11)) #> x = 10 returns 5.0 #> x = 11 returns 121 # 函數不能處理數組 # print('x = [10, 11, 12] returns ', foo([10, 11, 12])) # 錯誤
np.vectorize使標量函數也能處理數組,可選參數otypes爲輸出的類型.
# 函數向量化,向量化的輸出類型是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函數
首先定義一個二維數組
# 定義一個4x10的隨機二維數組 np.random.seed(100) arr_x = np.random.randint(1,10,size=[4,10]) arr_x #> array([[9, 9, 4, 8, 8, 1, 5, 3, 6, 3], #> [3, 3, 2, 1, 9, 5, 1, 7, 3, 5], #> [2, 6, 4, 5, 5, 4, 8, 2, 2, 8], #> [8, 1, 3, 4, 3, 6, 9, 2, 1, 8]])
若是咱們要找數組每行或每列的最大值,numpy的一個最大特色是基於向量化操做的,所以咱們使用np.apply_along_axis函數找每行或每列的最大值.
# 基於列操做,找每列的最大值 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函數
np.searchsorted函數返回某一變量在有序數組的位置,在該位置插入變量後數組仍然是有序的.
# 生成有序數組 x = np.arange(10) print('Where should 5 be inserted?: ', np.searchsorted(x, 5)) # 若遇到相同大小的數值,輸入變量放在右邊位置 print('Where should 5 be inserted (right)?: ', np.searchsorted(x, 5, side='right')) #> Where should 5 be inserted?: 5 #> Where should 5 be inserted (right)?: 6
7.4 如何增長數組維度
在不增長任何額外數據的前提下,np.newaxis函數能夠增長數組的維數,newaxis在的位置就是要增長的維度.
# 定義一維數組 x = np.arange(5) print('Original array: ', x) # 數組維度爲2 print('ndims of x:', x.ndim) # 列維度增長 x_col = x[:, np.newaxis] print(x_col) # 數組維度爲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) # 數組維度爲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函數
np.digitize函數返回數組每一個元素屬於bin的索引位置.
# 構建數組和bin x = np.arange(10) bins = np.array([0, 3, 6, 9]) # 返回bin索引位置 np.digitize(x, bins) #> array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4])
可視化分析digitize算法原理:
如上圖,根據變量落在bin的區間範圍,返回對應的索引.
7.7 Clip函數
np.clip函數將數字限制在給定截止範圍內,全部小於範圍下限的數被當成下限值,大於範圍上限的數被當成上限值.
# 限制x的全部元素位於3和8之間 np.clip(x, 3, 8) #> array([3, 3, 3, 3, 4, 5, 6, 7, 8, 8])
7.8 Histogram函數和Bincount函數
np.bincount函數統計最小值到最大值的個數,最小值爲0.
# Bincount例子 x = np.array([1,1,2,3,2,4,4,5,6,6,6]) np.bincount(x) # 0出現0次, 1出現2次, 2出現2次, 3出現1次,4出現2次,5出現1次,6出現3次 #> array([0, 2, 3, 0, 2, 1, 3], dtype=int64)
np.histogram函數統計數據落入bins的區間,不考慮bins兩側的區間(以下圖所示).
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]