轉自:DawnRanger的專欄
https://blog.csdn.net/DawnRanger/article/details/53125945
Numeric Python的簡稱,是幾乎所有python科學計算工具的基礎。主要功能:
- ndarray: 一個具有矢量運算和復雜廣播能力的快速並且節省空間的多維數組
- 面向數組的運算: 對於數組進行快速運算的標准數學函數
- 磁盤讀寫、內存映射
- 線性代數、隨機數、傅里葉變換
NumPy本身並沒有提供什么高級的數據分析能力,但是理解NumPy數組以及面向數組的計算將有利於使用pandas等工具。
2. ndarray:一種多維數組對象
ndarray是一個通用的同構數據多維容器,其中的所有元素必須是相同類型的。ndarray含有兩個屬性:
shape
: 一個表示各維度大小的數組dtype
:一個用於說明數據類型的對象
2.1 創建ndaray
1) array函數
它接受一切序列型的對象(list/set/tuple/ndarray/…)。除非顯式說明,np.array會嘗試為新建的這個數組推斷出一個較為合適的數據類型:
import numpy as np
arr1 = np.array([1,2,3,4,5])
arr2 = np.array([[1,2,3,4], [5,6,7,8]]) # 二維數組
- 1
- 2
- 3
- 4
2) zeros/ones/empty函數
創建指定長度或形狀的全0或全1或空數組,只需傳入一個表示形狀的元組(tuple)即可:
np.zeros(10)
np.ones((3,6)
np.empty((2,3,2)) #注意返回的並不是全0數組,而是未初始化的隨機值
- 1
- 2
- 3
- 4
3) linspace函數:linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
返回在start到stop之間均勻分布的num個數字,可以選擇是否包括stop. retstep表示是否返回步長.
np.linspace(1,5,5,True)
Out[4]: array([ 1., 2., 3., 4., 5.])
np.linspace(1,5,5,False)
Out[5]: array([ 1. , 1.8, 2.6, 3.4, 4.2])
- 1
- 2
- 3
- 4
- 5
- 6
3) arange函數:arange([start,] stop[, step,], dtype=None)
python內置函數range的數組版
np.arange(15)
- 1
- 2
4) 其它函數:
由於NumPy關注的是數值計算,因此,如果沒有特別指定,數據類型基本都是float64(浮點數)
array
將輸入轉換為ndarray,默認直接復制輸入數據asarray
將輸入轉換為ndarray,如果輸入本身就是一個ndarray就不進行復制ones_like
/zeros_like
/empty_like
以另一個數組為參數,並根據其形狀和dtype創建一個全0/全1/空數組eye
/identify
創建一個N×N” role=”presentation”>N×NN×N單位矩陣(對角線為1,其余為0)
2.2 ndaray的數據類型
dtype含有ndarray將一塊內存解釋為特定數據類型所需要的信息
arr1 = np.array([1,2,3], dtype = np.float64)
arr2 = np.array([1,2,3], dtype = np.int32)
arr2 = np.array([1,2,3], dtype = 'i4') # 也可以寫類型代碼
arr1.dtype
Out[5]: dtype('float64')
arr2.dtype
Out[6]: dtype('int32')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
NumPy的數據類型:
int8
/int16
/int32
/int64
有符號8/16/32/64位整數,類型代碼 i1/i2/i4/i8 (分別為1/2/4/8個字節)uint8
/uint16
/uint32
/uint64
無符號8/16/32/64位整數,類型代碼 u1/u2/u4/u8float16
/float32
/float64
/float128
浮點數,類型代碼 f2/f4/f8/f16complex64
/complex128
/complex256
復數,類型代碼 c8/c16/c32bool
布爾類型 ,類型代碼 ?object
Python對象類型,類型代碼 Ostring_
固定長度的字符串類型(每個字符一個字節),類型代碼 S 。例如,要創建一個長度為10的字符串,應使用S10unicode
固定長度的unicode類型,類型代碼 U 。同字符串(如U10)
數據類型轉換: astype方法
int_arr = np.array([1,2,3,4,5])
float_arr = int_arr.astype(np.float64)
numeric_str = np.array (['1.25', '-9.6', '42'], dtype = np.string_)
float_arr = numeric_str.astype(float) # 這里的float是Python的數據類型,NumPy會自動的將其映射到等價的dtype上,即np.float64
- 1
- 2
- 3
- 4
- 5
- 6
注意:astype無論如何都會創建出一個新的數組(原始數據的一分拷貝)
2.3 ndaray與標量的計算
使用數組運算的好處是不寫循環即可對數據進行批量運算,即矢量化(vectorization)。需要注意的是:
- 大小相等的數組之間的任何算術運算都會將運算應用到元素級
- 數組與標量的算術運算會將標量值傳播到各個元素
不同大小的數組之間的運算叫做廣播(broadcasting)。
2.4 索引與切片
2.4.1 一維數組
一維數組的索引與切片和Python列表的功能類似,區別在於,數組切片是原始數組的視圖,這意味着數據不會被復制,對視圖的任何修改都會直接反映到原數組上。NumPy如此設計的目的是為了處理大數據,如果采取復制的方法可能產生性能和內存的問題。
arr = np.arange(10)
arr[5:8] = 12
arr
Out[10]:array([0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
- 1
- 2
- 3
- 4
- 5
如果一定要復制可以使用copy方法顯式的復制。
2.4.2 多維數組
多維數組中,如果省略了后面的索引,則返回對象會是一個維度低一點的ndarray。例如,二維數組中,各索引位置上的元素不再是標量而是一維數組。
arr2d = np.array([[1,2,3], [4,5,6], [7,8,9]])
arr2d[2]
Out[11]:array([7, 8, 9])
arr2d[0][2]
arr2d[0,2] # 這兩種索引方法等價
- 1
- 2
- 3
- 4
- 5
- 6
2.4.3 多維數組切片
多維數組切片與一維數組稍有不同
arr2d = np.array([[1,2,3], [4,5,6], [7,8,9]])
arr2d[:2]
Out[1]: array([[1,2,3], [4,5,6]])
- 1
- 2
- 3
- 4
- 5
可以看出,它是按第0軸(第一個軸)切片的。切片是沿着一個軸向選取元素的。
可以一次傳入多個切片,也可以將整數索引和切片混合:
arr2d[:2, 1:]
Out[2]: aray([[2,3],
[5,6])
arr2d[1, :2]
Out[3]: array([4, 5])
arr2d[:, :1]
Out[4]: aray([[1],
[4],
[7]])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
2.4.4 布爾型索引
與算數運算類似,數組的比較運算(如==)也是矢量化的。
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7, 4) # 產生7x4的隨機數組
names == 'Bob'
Out[5]: array([True, False, False, True, False, False, False], dtype = bool)
data[names == 'Bob'] # 布爾索引
data[names = 'Bob', 2:] # 布爾索引與切片
data[-(names == 'Bob')]
mask = (names == 'Bob') | (names = 'Will') # 多個布爾條件用&(與)、|(或)等連接起來。(and/or無效)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
通過布爾型索引選取數組中的數據,將總是創建副本,即使返回一模一樣的數組。通過布爾型數組設置值是常用的手段。例如:
data[data<0] = 0 # 將data中的所有的負值都設為0
data[names != 'Joe'] = 7 # 將不為Joe的值設為7
- 1
- 2
- 3
2.4.5 花式索引(Fancy indexing)
利用整數數組進行索引。
正常情況下的索引:
In [17]: arr = np.empty((8,4))
In [18]: for i in range(8):
...: arr[i] = i # 矢量化賦值
In [19]: arr
Out[19]:
array([[ 0., 0., 0., 0.], [ 1., 1., 1., 1.], [ 2., 2., 2., 2.], [ 3., 3., 3., 3.], [ 4., 4., 4., 4.], [ 5., 5., 5., 5.], [ 6., 6., 6., 6.], [ 7., 7., 7., 7.]])
In [23]: arr[[4,3,0,6]] # 選取多行,注意要加括號[]
Out[23]:
array([[ 4., 4., 4., 4.], [ 3., 3., 3., 3.], [ 0., 0., 0., 0.], [ 6., 6., 6., 6.]])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
一次傳入多個索引數組時,它返回的是一個一維數組,其中的元素對應各個索引元組。
In [24]: arr = np.arange(32).reshape((8,4))
In [25]: arr
Out[25]:
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], [24, 25, 26, 27], [28, 29, 30, 31]])
In [26]: arr[[1,5,7,2], [0,2,1,3]]
Out[26]: array([ 4, 22, 29, 11])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
最終選出的元素是(1, 0)、(5, 3)、(7, 1)、(2, 2)。
如果想要選取數組的行列子集,可以采用以下方法:
In [33]: arr[[1,5,7,2]][:,[0,3,1,2]] # 可以把左右兩個[]分開來理解
Out[33]:
array([[ 4, 7, 5, 6], [20, 23, 21, 22], [28, 31, 29, 30], [ 8, 11, 9, 10]])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
另一種方法是使用 np.ix_ 函數,它可以將兩個一維整數數組轉換為一個用於選取方形區域的索引器:
In [34]: arr[np.ix_([1,5,7,2],[0,3,1,2])]
Out[34]:
array([[ 4, 7, 5, 6], [20, 23, 21, 22], [28, 31, 29, 30], [ 8, 11, 9, 10]])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
與切片不同,花式索引總是將數據復制到新數組中。
2.5 數組轉置和軸變換
返回原數據的視圖,不會進行任何復制。數組有transpose/swapaxes方法和T屬性。
3. numpy通用函數
一元函數:
abs/fabs
絕對值。對於非復數,可以使用更快的fabssqrt/square/exp/log/log10/log2/log1p
平方根/平方/指數/自然對數/底數為10的log/底數為2的logsign
返回元素的符號:1(正數)、0(零)、-1(負數)ceil/floor
取上界/下界整數rint
四舍五入到整數modf
返回數組的小數和正數兩個獨立的數組isnan
返回布爾數組,判斷是否為數字isfinite/isinf
是否有窮/無窮cos/cosh/sin/sinh/tan/tanh
普通和雙曲三角函數
二元函數:
add/subtract/multiply/divide/floor_divide
加/減/乘/除/向下圓整除法power
第一個數組中的是底數,第二個數組中的是指數maximum/fmax/minimum/fmin
最大最小值(fmax/fmin忽略NaN)mod
取模copysign
將第二個數組中的值的符號復制給第一個數組中greater/greater_equal/less/less_equal
元素級比較,產生布爾數組。logical_and/logical_or/logical_xor
元素級真值邏輯運算。&、|、^。
4. 利用數組進行數據處理
一般來說矢量化數組運算要比等價的純Python方式快上一兩個數量級,尤其是各種數值計算。廣播是一種針對矢量化計算的強大手段。
4.1 將條件邏輯表述為數組運算
numpy.where
函數是三元表達式 x if condition else y
的矢量化版本:where(condition, [x, y])
arr = randn(4,4)
np.where(arr>0, 2, -2) # 爭執設置為2,負值設置為-2
np.where(arr>0, 2, arr) # 只講正值設置為2
- 1
- 2
- 3
- 4
條件是可以嵌套的:
np.where(cond1 & cond2, 0,
np.where(cond1, 1,
np.where(cond2, 2, 3)))
- 1
- 2
- 3
- 4
4.2 數學和統計方法
聚合計算(aggregation):既能當數組的實例方法調用,也可以當做頂級NumPy函數使用;可接受一個 axis 參數
- sum
/mean
/std
/var
/min
/max
/argmin
/argmax
求和,平均數,標准差,方差,最大值,最小值,最大最小元素的索引
不聚合,產生一個由中間結果組成的數組:
- cumsum
、cumprod
所有元素的累積和/累計積
4.3 用於布爾型數組的方法
bools = np.array([False, False, True, False])
(bools>0).sum() # 正值的數量
bools.any() # 測試數組中是否存在一個或多個True
bools.all() # 檢查數組中所有值是否都是True
- 1
- 2
- 3
- 4
- 5
4.4 排序
Numpy數組自帶sort方法,如果需要在某一個軸向上進行排序,只需要將軸編號傳遞給sort.
頂級方法np.sort返回的是數組已排序的副本,而數組自帶sort方法則會直接修改數組本身.
arr = randn(5, 3)
arr.sort(1)
large_arr = randn(1000)
large_arr.sort()
large_arr[int(0.05 * len(large_arr))] # 5%分位數
- 1
- 2
- 3
- 4
- 5
- 6
4.5 唯一化以及其它的集合邏輯
集合運算函數:
unique(x)
返回唯一元素intersect1d(x,y)
交集union1d(x,y)
並集in1d(x,y)
布爾型數組,表示x中的元素是否存在於y中setdiff1d(x,y)
差setxor1d(x,y)
異或
5. 用於數組的文件操作
二進制文件: np.save
、 np.load
文本文件: np.loadtxt
、 np.savetxt
6. 線性代數
常用numpy.linalg函數
dot
矩陣乘法。兩個一維數組計算點乘,兩個多維數組計算叉乘diag
返回矩陣對角線元素trace
對角線元素和det
行列式eig
特征值、特征向量inv
逆qr
QR分解svd
奇異值分解solve
解線性方程Ax=blstsq
計算Ax=b的最小二乘解
7. 隨機數生成
生成隨機數的方法:
rand
均勻分布的樣本值randint
給定上下限的隨機整數randn
標准正態分布binomial
二項分布normal
正態分布chisquare
卡方分布gamma
Gamma分布uniform
[0,1]之間的均勻分布