一、NumPy簡介
NumPy是Python語言的一個擴充程序庫。支持高級大量的維度數組與矩陣運算,此外也針對數組運算提供大量的數學函數庫。Numpy內部解除了CPython的GIL(全局解釋器鎖),運行效率極好,是大量機器學習框架的基礎庫!
關於GIL請參考博客:http://www.cnblogs.com/wj-1314/p/9056555.html
NumPy的全名為Numeric Python,是一個開源的Python科學計算庫,它包括:
- 一個強大的N維數組對象ndrray;
- 比較成熟的(廣播)函數庫;
- 用於整合C/C++和Fortran代碼的工具包;
- 實用的線性代數、傅里葉變換和隨機數生成函數
NumPy的優點:
- 對於同樣的數值計算任務,使用NumPy要比直接編寫Python代碼便捷得多;
- NumPy中的數組的存儲效率和輸入輸出性能均遠遠優於Python中等價的基本數據結構,且其能夠提升的性能是與數組中的元素成比例的;
- NumPy的大部分代碼都是用C語言寫的,其底層算法在設計時就有着優異的性能,這使得NumPy比純Python代碼高效得多
當然,NumPy也有其不足之處,由於NumPy使用內存映射文件以達到最優的數據讀寫性能,而內存的大小限制了其對TB級大文件的處理;此外,NumPy數組的通用性不及Python提供的list容器。因此,在科學計算之外的領域,NumPy的優勢也就不那么明顯。
關於Python Numpy矩陣的用法總結請參考博文:https://www.cnblogs.com/wj-1314/p/10244807.html
二,numpy保存二進制文件(.npy/.npz)
ndarray對象可以保存到磁盤文件並從磁盤文件加載,可用的IO功能有:
- load()和save() 函數處理Numpy 二進制文件(帶npy擴展名)。
- loadtxt() 和savetxt() 函數處理正常的文本文件。
Numpy為ndarray對象引入了一個簡單的文件格式,這個npy文件在磁盤文件中,存儲重建ndarray所需的數據,圖形,dtype和其他信息,以便正確獲取數組,即使該文件在具有不同架構的一台機器上。
numpy.load和numpy.save函數式以Numpy專用的二進制類型保存數據,這兩個函數會自動處理元素類型和shape等信息,使用它們讀寫數組就方便多了,但是numpy.save輸出的文件很難和其他語言編寫的程序讀入。
1,numpy.save
保存一個數組到一個二進制的文件中,保存格式是.npy
參數介紹:
numpy.save(file, arr, allow_pickle=True, fix_imports=True) file:文件名/文件路徑 arr:要存儲的數組 allow_pickle:布爾值,允許使用Python pickles保存對象數組(可選參數,默認即可) fix_imports:為了方便Pyhton2中讀取Python3保存的數據(可選參數,默認即可)
舉例說明:
>>> import numpy as np #生成數據 >>> x=np.arange(10) >>> x array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) #數據保存 >>> np.save('save_x',x) #讀取保存的數據 >>> np.load('save_x.npy') array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2,numpy.savez
這個同樣是保存數組到一個二進制的文件中,但是厲害的是,它可以保存多個數組到同一個文件中,保存格式為.npz,它們其實就是多個前面np.save的保存的npy,再通過打包(未壓縮)的方式把這些文件歸到一個文件上,不行你再去解壓npz文件就知道自己保存的是多個npy。
參數介紹:
numpy.savez(file, *args, **kwds) file:文件名/文件路徑 *args:要存儲的數組,可以寫多個,如果沒有給數組指定Key,Numpy將默認從'arr_0','arr_1'的方式命名 kwds:(可選參數,默認即可)
舉例說明:
>>> import numpy as np #生成數據 >>> x=np.arange(10) >>> x array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> y=np.sin(x) >>> y array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 , -0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849]) #數據保存 >>> np.save('save_xy',x,y) #讀取保存的數據 >>> npzfile=np.load('save_xy.npz') >>> npzfile #是一個對象,無法讀取 <numpy.lib.npyio.NpzFile object at 0x7f63ce4c8860> #按照組數默認的key進行訪問 >>> npzfile['arr_0'] array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> npzfile['arr_1'] array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 , -0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849])
更加神奇的是,我們可以不適用Numpy給數組的key,而是自己給數組有意義的key,這樣就可以不用去猜測自己加載數據是否是自己需要的。
#數據保存 >>> np.savez('newsave_xy',x=x,y=y) #讀取保存的數據 >>> npzfile=np.load('newsave_xy.npz') #按照保存時設定組數key進行訪問 >>> npzfile['x'] array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> npzfile['y'] array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 , -0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849])
在深度學習中,我們保存了訓練集,驗證集,測試集,還包括它們的標簽,用這個方式存儲起來,要加載什么有什么,文件數量大大減少,也不會到處改文件名。
3,savetxt()
以簡單文本文件格式存儲和獲取數組數據,通過savetxt()和loadtxt()函數來完成的。
import numpy as np a = np.array([1,2,3,4,5]) np.savetxt('out.txt',a) b = np.loadtxt('out.txt') print(b) # [1. 2. 3. 4. 5.]
savetxt()和loadtxt()函數接受附加的可選參數,例如頁首,頁尾和分隔符。
4,csv文件轉化為npy格式
下面有一個csv文件的數據,我想將其轉化為npy格式,數據內容如下:
cut,flute_1,flute_2,flute_3 1,31.41635516,19.48369225,21.74806264 2,34.8927704,23.473047,24.92595987 3,38.10284657,27.17286849,27.89865916 4,41.06102301,30.59930868,30.67784802 5,43.78119133,33.76786983,33.27472071 6,46.27671037,36.69342355,35.6999933 7,48.56042098,39.39022937,37.96391852 8,50.64466037,41.87195302,40.07630017 9,52.54127629,44.15168423,42.04650728
首先,數據是有索引,序列的,所以我們讀取的時候要注意,轉化代碼如下:
import pandas as pd import numpy as np file1 = 'Train_A_wear.csv' data1 = pd.read_csv(file1,header=0,index_col=0) np.save('train_A_wear.npy',data1.values) data_A_wear = np.load('trainA_wear.npy')
三、數組ndarray
Numpy中定義的最重要的對象是成為ndarray的N維數組類型。它描述相同類型的元素集合。可以使用基於零的索引訪問集合中的項目。
大部分的數組操作僅僅是修改元數據部分,而不改變其底層的實際數據。數組的維數稱為秩,簡單來說就是如果你需要獲取數組中一個特定元素所需的坐標數,如a是一個2×3×4的矩陣,你索引其中的一個元素必須給定三個坐標a[x,y,z],故它的維數就是3。
我們可以直接將數組看作一種新的數據類型,就像list、tuple、dict一樣,但數組中所有元素的類型必須是一致的,Python支持的數據類型有整型、浮點型以及復數型,但這些類型不足以滿足科學計算的需求,因此NumPy中添加了許多其他的數據類型,如bool、inti、int64、float32、complex64等。同時,它也有許多其特有的屬性和方法。
3.1 常用ndarray屬性:
- dtype 描述數組元素的類型
- shape 以tuple表示的數組形狀
- ndim 數組的維度
- size 數組中元素的個數
- itemsize 數組中的元素在內存所占字節數
- T 數組的轉置
- flat 返回一個數組的迭代器,對flat賦值將導致整個數組的元素被覆蓋
- real/imag 給出復數數組的實部/虛部
- nbytes 數組占用的存儲空間
import numpy as np # 創建簡單的列表 a = [1,2,3,4,5,6] # 講列表轉換為數組 b = np.array(a) # Numpy查看數組屬性 print(b.size) #6 # 數組形狀 print(b.shape) # (6,) # 數組維度 print(b.ndim) # 1 # 數組元素類型 print(b.dtype) # int32
import numpy as np a = np.array([1,2,3]) print(a) # [1 2 3] # 多於一個維度 a = np.array([[1, 2], [3, 4]]) print(a) # [[1 2] # [3 4]] # 最小維度 a = np.array([1, 2, 3,4,5], ndmin = 2) print(a) # [[1 2 3 4 5]] # dtype 參數 a = np.array([1, 2, 3], dtype = complex) print(a) # [1.+0.j 2.+0.j 3.+0.j]
ndarray 對象由計算機內存中的一維連續區域組成,帶有將每個元素映射到內存塊中某個位置的索引方案。 內存塊以按行(C 風格)或按列(FORTRAN 或 MatLab 風格)的方式保存元素。
3.2 常用ndarray方法:
- reshape(…) 返回一個給定shape的數組的副本
- resize(…) 返回給定shape的數組,原數組shape發生改變
- flatten()/ravel() 返回展平數組,原數組不改變
- astype(dtype) 返回指定元素類型的數組副本
- fill() 將數組元素全部設定為一個標量值
- sum/Prod() 計算所有數組元素的和/積
- mean()/var()/std() 返回數組元素的均值/方差/標准差
- max()/min()/ptp()/median() 返回數組元素的最大值/最小值/取值范圍/中位數
- argmax()/argmin() 返回最大值/最小值的索引
- sort() 對數組進行排序,axis指定排序的軸;kind指定排序算法,默認是快速排序
- view()/copy() view創造一個新的數組對象指向同一數據;copy是深復制
- tolist() 將數組完全轉為列表,注意與直接使用list(array)的區別
- compress() 返回滿足條件的元素構成的數組
numpy.reshape:
import numpy as np a = np.arange(8) print('原始數組:') print(a) print('\n') b = a.reshape(4,2) print('修改后的數組:') print(b) '''結果 原始數組: [0 1 2 3 4 5 6 7] 修改后的數組: [[0 1] [2 3] [4 5] [6 7]] '''
numpy.ndarray.flatten:
import numpy as np a = np.arange(8).reshape(2,4) print('原數組:') print(a) print('\n') # default is column-major print('展開的數組:') print(a.flatten()) print('\n') print('以 F 風格順序展開的數組:') print(a.flatten(order = 'F')) '''結果: 原數組: [[0 1 2 3] [4 5 6 7]] 展開的數組: [0 1 2 3 4 5 6 7] 以 F 風格順序展開的數組: [0 4 1 5 2 6 3 7] '''
numpy.ravel:
import numpy as np a = np.arange(8).reshape(2,4) print('原數組:') print(a) print('\n') print('調用 ravel 函數之后:') print(a.ravel()) print('\n') print('以 F 風格順序調用 ravel 函數之后:') print(a.ravel(order = 'F')) '''結果: 原數組: [[0 1 2 3] [4 5 6 7]] 調用 ravel 函數之后: [0 1 2 3 4 5 6 7] 以 F 風格順序調用 ravel 函數之后: [0 4 1 5 2 6 3 7]'''
3.3 數組的創建
numpy中使用array()函數創建數組,array的首個參數一定是一個序列,可以是元組也可以是列表。
3.3.1 一維數組的創建
可以使用numpy中的arange()函數創建一維有序數組,它是內置函數range的擴展版。
In [1]: import numpy as np In [2]: ls1 = range(10) In [3]: list(ls1) Out[3]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [4]: type(ls1) Out[4]: range In [5]: ls2 = np.arange(10) In [6]: list(ls2) Out[6]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [7]: type(ls2) Out[7]: numpy.ndarray
通過arange生成的序列就不是簡簡單單的列表類型了,而是一個一維數組。
如果一維數組不是一個規律的有序元素,而是人為的輸入,就需要array()函數創建了。
In [8]: arr1 = np.array((1,20,13,28,22)) In [9]: arr1 Out[9]: array([ 1, 20, 13, 28, 22]) In [10]: type(arr1) Out[10]: numpy.ndarray
上面是由元組序列構成的一維數組。
In [11]: arr2 = np.array([1,1,2,3,5,8,13,21]) In [12]: arr2 Out[12]: array([ 1, 1, 2, 3, 5, 8, 13, 21]) In [13]: type(arr2) Out[13]: numpy.ndarray
上面是由列表序列構成的一維數組。
3.3.2 二維數組的創建
二維數組的創建,其實在就是列表套列表或元組套元組。
In [14]: arr3 = np.array(((1,1,2,3),(5,8,13,21),(34,55,89,144))) In [15]: arr3 Out[15]: array([[ 1, 1, 2, 3], [ 5, 8, 13, 21], [ 34, 55, 89, 144]])
上面使用元組套元組的方式。
In [16]: arr4 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]]) In [17]: arr4 Out[17]: array([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]])
上面使用列表套列表的方式。
對於高維數組在將來的數據分析中用的比較少,這里關於高維數組的創建就不贅述了,構建方法仍然是套的方式。
上面所介紹的都是人為設定的一維、二維或高維數組,numpy中也提供了幾種特殊的數組,它們是:
In [18]: np.ones(3) #返回一維元素全為1的數組 Out[18]: array([ 1., 1., 1.]) In [19]: np.ones([3,4]) #返回元素全為1的3×4二維數組 Out[19]: array([[ 1., 1., 1., 1.], [ 1., 1., 1., 1.], [ 1., 1., 1., 1.]]) In [20]: np.zeros(3) #返回一維元素全為0的數組 Out[20]: array([ 0., 0., 0.]) In [21]: np.zeros([3,4]) #返回元素全為0的3×4二維數組 Out[21]: array([[ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.]]) In [22]: np.empty(3) #返回一維空數組 Out[22]: array([ 0., 0., 0.]) In [23]: np.empty([3,4]) #返回3×4二維空數組 Out[23]: array([[ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.]])
3.3.3 ones函數
返回特定大小,以1填充的新數組
>>> import numpy as np >>> a=np.ones(3);a array([ 1., 1., 1.]) >>> b=np.ones((3,2));b array([[ 1., 1.], [ 1., 1.], [ 1., 1.]])
3.3.4 zeros函數
返回特定大小,以0填充的新數組。
官方庫的解釋:
def zeros(shape, dtype=None, order='C'): # real signature unknown; restored from __doc__ """ zeros(shape, dtype=float, order='C') Return a new array of given shape and type, filled with zeros. Parameters ---------- shape : int or tuple of ints Shape of the new array, e.g., ``(2, 3)`` or ``2``. dtype : data-type, optional The desired data-type for the array, e.g., `numpy.int8`. Default is `numpy.float64`. order : {'C', 'F'}, optional, default: 'C' Whether to store multi-dimensional data in row-major (C-style) or column-major (Fortran-style) order in memory. Returns ------- out : ndarray Array of zeros with the given shape, dtype, and order. See Also -------- zeros_like : Return an array of zeros with shape and type of input. empty : Return a new uninitialized array. ones : Return a new array setting values to one. full : Return a new array of given shape filled with value. Examples -------- >>> np.zeros(5) array([ 0., 0., 0., 0., 0.]) >>> np.zeros((5,), dtype=int) array([0, 0, 0, 0, 0]) >>> np.zeros((2, 1)) array([[ 0.], [ 0.]]) >>> s = (2,2) >>> np.zeros(s) array([[ 0., 0.], [ 0., 0.]]) >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype array([(0, 0), (0, 0)], dtype=[('x', '<i4'), ('y', '<i4')]) """ pass
numpy.zeros(shape, dtype=float, order=’C’)
參數:
shape:int或ints序列 新數組的形狀,例如(2,3 )或2。 dtype:數據類型,可選 數組的所需數據類型,例如numpy.int8。默認值為 numpy.float64。 order:{'C','F'},可選 是否在存儲器中以C或Fortran連續(按行或列方式)存儲多維數據。
返回:
out:ndarray 具有給定形狀,數據類型和順序的零數組。
>>> c=np.zeros(3) >>> c array([ 0., 0., 0.]) >>> d=np.zeros((2,3));d array([[ 0., 0., 0.], [ 0., 0., 0.]]) #d=np.zeros(2,3)會報錯,d=np.zeros(3,dtype=int)來改變默認的數據類型
3.3.5 eye&identity函數
eye()函數用於生成指定行數的單位矩陣
>>> e=np.eye(3);e array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> e=np.eye(3,2);e array([[ 1., 0.], [ 0., 1.], [ 0., 0.]]) >>> e=np.eye(3,1);e array([[ 1.], [ 0.], [ 0.]]) >>> e=np.eye(3,3);e array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> e=np.eye(3,3,1);e array([[ 0., 1., 0.], [ 0., 0., 1.], [ 0., 0., 0.]]) e=np.eye(3,3,2);e array([[ 0., 0., 1.], [ 0., 0., 0.], [ 0., 0., 0.]]) >>> e=np.eye(3,3,3);e array([[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) >>> e=np.eye(3,3,4);e array([[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) >>> p=np.identity(4);p array([[ 1., 0., 0., 0.], [ 0., 1., 0., 0.], [ 0., 0., 1., 0.], [ 0., 0., 0., 1.]]) >>> p=np.identity(4,3);p #會報錯 >>> p=np.identity((4,3));p #會報錯
3.3.6 empty函數
它創建指定形狀和dtype的未初始化數組。它使用以下構造函數:
numpy.empty(shape, dtype = float, order = 'C')
注意:數組為隨機值,因為他們未初始化。
import numpy as np x = np.empty([3,2], dtype = int) print(x) # [[1762 0] # [ 0 0] # [ 0 0]]
>>> a=np.empty(3);a array([ 1.60091154e-163, 1.12069303e-258, 3.23790862e-318]) >>> a=np.empty((3,3));a array([[ 1.57741456e-284, 1.57680914e-284, 1.56735002e-163], [ 1.56205068e-163, 1.62511438e-163, 1.21880041e+171], [ 1.57757869e-052, 7.34292780e+223, 4.71235856e+257]])
3.3.7 ones_like zero_like empy_like函數
>>> a=np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]]) >>> a.shape (3, 2, 2) >>> b=np.ones_like(a) >>> b array([[[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]]]) >>> b=np.zeros_like(a);b array([[[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]]) >>> a=np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]]) >>> b=np.empty_like(a);b array([[[39125057, 40012256], [81313824, 81313856]], [[ 0, 0], [ 0, 0]], [[ 0, 0], [ 0, 0]]]) #注意,shape和dtype均復制
3.3.8 .T函數
.T 作用於矩陣,用於求矩陣的轉置
>>myMat=np.mat([[1,2,3],[4,5,6]]) >>print(myMat) >>matrix([[1.,2.,3.] [4.,5.,6.]]) >>print(myMat.T) >>matrix([[1,4], [2,5], [3,6]])
3.3.9 tolist()函數
tolost()函數用於把一個矩陣轉化為list列表
>>x=np.mat([[1,2,3],[4,5,6]]) >>print(x) >>matrix([[1,2,3],[4,,5,6]]) >>type(x) >>matrix >>x.tolist() >>[[1,2,3],[4,5,6]]
3.3.10 .I
.I用於求矩陣的逆矩陣,逆矩陣在計算中是經常要用到的,例如一個矩陣A,求A的逆矩陣B,即存在矩陣B是AB=I(I是單位)
In [3]: a=mat([[1,2,3],[4,5,6]]) In [4]: a Out[4]: matrix([[1, 2, 3], [4, 5, 6]]) In [5]: a.I Out[5]: matrix([[-0.94444444, 0.44444444], [-0.11111111, 0.11111111], [ 0.72222222, -0.22222222]]) In [6]: s=a.I In [8]: a*s Out[8]: matrix([[ 1.00000000e+00, 3.33066907e-16], [ 0.00000000e+00, 1.00000000e+00]])
3.3.11 .power(x1,x2)
數組的元素分別求n次方,x2可以是數字,也可以是數組,但是x1和x2的列數要相同。
>>> x1 = range(6) >>> x1 [0, 1, 2, 3, 4, 5] >>> np.power(x1, 3) array([ 0, 1, 8, 27, 64, 125])
>>> x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0] >>> np.power(x1, x2) array([ 0., 1., 8., 27., 16., 5.])
>>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]]) >>> x2 array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]]) >>> np.power(x1, x2) array([[ 0, 1, 8, 27, 16, 5], [ 0, 1, 8, 27, 16, 5]])
3.3.12 reshape() 函數
一般用法:numpy.arrange(n).reshape(a,b)
意思:依次生成n個自然數,並且以a行b列的數組形式顯示。
In [1]: np.arange(16).reshape(2,8) #生成16個自然數,以2行8列的形式顯示 Out[1]: array([[ 0, 1, 2, 3, 4, 5, 6, 7], [ 8, 9, 10, 11, 12, 13, 14, 15]])
特殊用法:mat(or array).reshape(c,-1)
必須是矩陣格式或者數組格式,才能使用.reshape(c,-1)函數,表示將此矩陣或者數組重組,以c行d 列的形式表示(-1的作用就在此,自動計算d:d=數組或者矩陣里面所有的元素個數(c,d必須為整數,不然會報錯))
In [2]: arr=np.arange(16).reshape(2,8) out[2]: In [3]: arr out[3]: array([[ 0, 1, 2, 3, 4, 5, 6, 7], [ 8, 9, 10, 11, 12, 13, 14, 15]]) In [4]: arr.reshape(4,-1) #將arr變成4行的格式,列數自動計算的(c=4, d=16/4=4) out[4]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) In [5]: arr.reshape(8,-1) #將arr變成8行的格式,列數自動計算的(c=8, d=16/8=2) out[5]: array([[ 0, 1], [ 2, 3], [ 4, 5], [ 6, 7], [ 8, 9], [10, 11], [12, 13], [14, 15]]) In [6]: arr.reshape(10,-1) #將arr變成10行的格式,列數自動計算的(c=10, d=16/10=1.6 != Int) out[6]: ValueError: cannot reshape array of size 16 into shape (10,newaxis)
3.3.13 np.unique()的用法
該函數是去除數組中的重復數字,並進行排序之后輸出
a = [2,3,4,1,21,32,32,32,2,1] b = [1,2,3,1,2,3] c = [[1,2,3],[1,2,3],[2,3,4]] resa = np.unique(a) resb = np.unique(b) resc = np.unique(c) print('unique result a is :',resa) print('unique result a is :',resb) print('unique result a is :',resc) ''' unique result a is : [ 1 2 3 4 21 32] unique result a is : [1 2 3] unique result a is : [1 2 3 4] '''
3.3.14 np.argsort()的用法
argsort()函數返回的是數組值從小到達的索引值
One dimensional array:一維數組 >>> x = np.array([3, 1, 2]) >>> np.argsort(x) array([1, 2, 0]) Two-dimensional array:二維數組 >>> x = np.array([[0, 3], [2, 2]]) >>> x array([[0, 3], [2, 2]]) >>> np.argsort(x, axis=0) #按列排序 array([[0, 1], [1, 0]]) >>> np.argsort(x, axis=1) #按行排序 array([[0, 1], [0, 1]])
舉個例子:
>>> x = np.array([3, 1, 2]) >>> np.argsort(x) #按升序排列 array([1, 2, 0]) >>> np.argsort(-x) #按降序排列 array([0, 2, 1]) >>> x[np.argsort(x)] #通過索引值排序后的數組 array([1, 2, 3]) >>> x[np.argsort(-x)] array([3, 2, 1]) 另一種方式實現按降序排序: >>> a = x[np.argsort(x)] >>> a array([1, 2, 3]) >>> a[::-1] array([3, 2, 1])
3.3.15 np.flatnonzero()
該函數輸入一個矩陣,返回扁平化后矩陣中非零元素的位置(index)
下面給出一個用法,輸入一個矩陣,返回了其中非零元素的位置:
>>> x = np.arange(-2, 3) >>> x array([-2, -1, 0, 1, 2]) >>> np.flatnonzero(x) array([0, 1, 3, 4]) import numpy as np d = np.array([1,2,3,4,4,3,5,3,6]) haa = np.flatnonzero(d == 3) print (haa) [2 5 7]
對向量元素的判斷 d == 3,返回了一個和向量等長的由0/1組成的矩陣,然后再調用函數,返回的位置,就是對應要找的元素的位置。
# Visualize some examples from the dataset. # We show a few examples of training images from each class. classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] #類別列表 num_classes = len(classes) #類別數目 samples_per_class = 7 # 每個類別采樣個數 for y, cls in enumerate(classes): # 對列表的元素位置和元素進行循環,y表示元素位置(0,num_class),cls元素本身'plane'等 idxs = np.flatnonzero(y_train == y) #找出標簽中y類的位置 idxs = np.random.choice(idxs, samples_per_class, replace=False) #從中選出我們所需的7個樣本 for i, idx in enumerate(idxs): #對所選的樣本的位置和樣本所對應的圖片在訓練集中的位置進行循環 plt_idx = i * num_classes + y + 1 # 在子圖中所占位置的計算 plt.subplot(samples_per_class, num_classes, plt_idx) # 說明要畫的子圖的編號 plt.imshow(X_train[idx].astype('uint8')) # 畫圖 plt.axis('off') if i == 0: plt.title(cls) # 寫上標題,也就是類別名 plt.show() # 顯示
3.3.16 np.nonzero()
nonzero函數是numpy中用於得到數組array中非零元素的目錄(位置)的函數。
返回值為元組,兩個值分別為兩個維度,包含了相應維度上非零元素的目錄值。
只有a中非零元素才會有索引值,那些零值元素沒有索引值
當使用布爾數組直接作為下標對象或者元祖下標對象中有布爾數組時,都相當於用nonzero()講布爾數組轉換成一組整數數組,然后使用整數數組進行下標運算。
nonzeros(a)返回數組a中值不為零的元素的下標,它的返回值是一個長度為a.ndim(數組a的軸數)的元組,元組的每個元素都是一個整數數組,其值為非零元素的下標在對應軸上的值。例如對於一維布爾數組b1,nonzero(b1)所得到的是一個長度為1的元組,它表示b1[0]和b1[2]的值不為0(False)。
b = np.array([True,False,True,False]) b array([ True, False, True, False]) np.nonzero(b) (array([0, 2], dtype=int64),)
對於一個二維數組c,nonzeero(c)所得到的是一個長度為2的元祖,它的第0個元素是數組a中值不為0的元素的第0軸的下標,第一個元素則為第1軸的下標,因此從下面的結果可知b2[0,0]、b[0,2]和b2[1,0]的值不為0:
c = np.array([[True, False, True], [True, False, False]]) c array([[ True, False, True], [ True, False, False]]) np.nonzero(c) (array([0, 0, 1], dtype=int64), array([0, 2, 0], dtype=int64))
3.3.17 np.column_stack(tup)
np.column_stack(tup)相當於np.concatenate((a1, a2, …), axis=1),對豎軸的數組進行橫向的操作。
官方解釋(如果傳遞的是一個一維數組,則會先將一維數組轉化為2維數組):
Stack 1-D arrays as columns into a 2-D array. Take a sequence of 1-D arrays and stack them as columns to make a single 2-D array. 2-D arrays are stacked as-is, just like with `hstack`. 1-D arrays are turned into 2-D columns first. Parameters ---------- tup : sequence of 1-D or 2-D arrays. Arrays to stack. All of them must have the same first dimension. Returns ------- stacked : 2-D array The array formed by stacking the given arrays. See Also -------- stack, hstack, vstack, concatenate
舉例說明:
如果開始傳入的是一維數組,首先將一維數組轉化為二維數組
import numpy as np a = np.array((1, 2, 3)) b = np.array((2, 3, 4)) c = np.column_stack((a, b)) print(a) print(b) print(c) # 結果: [1 2 3] [2 3 4] [[1 2] [2 3] [3 4]]
如果一開始傳入的是多維數組,則直接進行拼接操作
import numpy as np a = np.array(((1, 2, 3), (4, 3, 2))) b = np.array(((2,3,4),(2,12,2))) c = np.column_stack((a,b)) print(a) print(b) print(c) # 結果: [[1 2 3] [4 3 2]] [[ 2 3 4] [ 2 12 2]] [[ 1 2 3 2 3 4] [ 4 3 2 2 12 2]]
四,Numpy數據類型
NumPy 支持比 Python 更多種類的數值類型。 下表顯示了 NumPy 中定義的不同標量數據類型。
序號 | 數據類型及描述 |
---|---|
1. | bool_存儲為一個字節的布爾值(真或假) |
2. | int_默認整數,相當於 C 的long,通常為int32或int64 |
3. | intc相當於 C 的int,通常為int32或int64 |
4. | intp用於索引的整數,相當於 C 的size_t,通常為int32或int64 |
5. | int8字節(-128 ~ 127) |
6. | int1616 位整數(-32768 ~ 32767) |
7. | int3232 位整數(-2147483648 ~ 2147483647) |
8. | int6464 位整數(-9223372036854775808 ~ 9223372036854775807) |
9. | uint88 位無符號整數(0 ~ 255) |
10. | uint1616 位無符號整數(0 ~ 65535) |
11. | uint3232 位無符號整數(0 ~ 4294967295) |
12. | uint6464 位無符號整數(0 ~ 18446744073709551615) |
13. | float_float64的簡寫 |
14. | float16半精度浮點:符號位,5 位指數,10 位尾數 |
15. | float32單精度浮點:符號位,8 位指數,23 位尾數 |
16. | float64雙精度浮點:符號位,11 位指數,52 位尾數 |
17. | complex_complex128的簡寫 |
18. | complex64復數,由兩個 32 位浮點表示(實部和虛部) |
19. | complex128復數,由兩個 64 位浮點表示(實部和虛部) |
NumPy 數字類型是dtype(數據類型)對象的實例,每個對象具有唯一的特征。 這些類型可以是np.bool_,np.float32等。
4.1 數據類型對象(dtype)
數據類型對象描述了對應於數組的固定內存塊的解釋,取決於以下方面:
-
數據類型(整數、浮點或者 Python 對象)
-
數據大小
-
字節序(小端或大端)
-
在結構化類型的情況下,字段的名稱,每個字段的數據類型,和每個字段占用的內存塊部分。
-
如果數據類型是子序列,它的形狀和數據類型。
字節順序取決於數據類型的前綴<或>。<意味着編碼是小端(最小有效字節存儲在最小地址中)。>意味着編碼是大端(最大有效字節存儲在最小地址中)。
dtype語法構造:
numpy.dtype(object, align, copy)
參數為:
Object:被轉換為數據類型的對象。 Align:如果為true,則向字段添加間隔,使其類似 C 的結構體。 Copy: 生成dtype對象的新副本,如果為flase,結果是內建數據類型對象的引用。
示例:
# 使用數組標量類型 import numpy as np dt = np.dtype(np.int32) print(dt) # int32 # int8,int16,int32,int64 可替換為等價的字符串 'i1','i2','i4',以及其他。 dt = np.dtype('i4') print(dt) # int32 # 使用端記號 dt = np.dtype('>i4') print(dt) # >i4 # 首先創建結構化數據類型。 dt = np.dtype([('age',np.int8)]) print(dt) # [('age', 'i1')] # 現在將其應用於 ndarray 對象 dt = np.dtype([('age',np.int8)]) a = np.array([(10,),(20,),(30,)], dtype = dt) print(a) # [(10,) (20,) (30,)] # 文件名稱可用於訪問 age 列的內容 dt = np.dtype([('age',np.int8)]) a = np.array([(10,),(20,),(30,)], dtype = dt) print(a['age']) # [10 20 30]
五,Numpy 切片和索引
ndarray對象的內容可以通過索引或切片來訪問和修改,就像python的內置容器對象一樣。
nadarray 對象中的元素遵循基於零的索引,有三種可用的索引方法類型:字段訪問,基礎切片和高級索引。
基本切片是Python中基本切片概念到n維的擴展,通過start,stop和step參數提供給內置函數的slice函數來構造一個Python slice對象,此slice對象被傳遞給數組來提取數組的一部分。
練習:
import numpy as np a = np.arange(10) print(a) # [0 1 2 3 4 5 6 7 8 9] s = slice(2,7,2) print(s) # slice(2, 7, 2) print(a[s]) # [2 4 6] b = a[2:7:2] print(b) # [2 4 6] # 對單個元素進行切片 b = a[5] print(b) # 5 # 對始於索引的元素進行切片 print(a[2:]) # [2 3 4 5 6 7 8 9] # 對索引之間的元素進行切片 print(a[2:5]) # [2 3 4] # 二維數組 # 最開始的數組 import numpy as np a = np.array([[1,2,3],[3,4,5],[4,5,6]]) print('我們的數組是:') print(a) print ('\n') # 這會返回第二列元素的數組: print ('第二列的元素是:') print(a[...,1]) print('\n') # 現在我們從第二行切片所有元素: print ('第二行的元素是:') print(a[1,...]) print( '\n') # 現在我們從第二列向后切片所有元素: print ('第二列及其剩余元素是:') print(a[...,1:]) ''' 我們的數組是: [[1 2 3] [3 4 5] [4 5 6]] 第二列的元素是: [2 4 5] 第二行的元素是: [3 4 5] 第二列及其剩余元素是: [[2 3] [4 5] [5 6]]'''
六,numpy中的ndarray與array的區別
答:Well, np.array is just a convenience function to create an ndarray, it is not a class itself.
(嗯,np.array只是一個便捷的函數,用來創建一個ndarray,它本身不是一個類)
You can also create an array using np.ndarray, but it is not the recommended way. From the docstring of np.ndarray:
(你也能夠用np.ndarray來創建,但這不是推薦的方式。來自np.ndarray的文檔:)
numpy函數:shape用法
