Numpy 數組ndarray和常用函數速查


轉自:DawnRanger的專欄
https://blog.csdn.net/DawnRanger/article/details/53125945





1. 簡介

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/u8
  • float16/float32/float64/float128 浮點數,類型代碼 f2/f4/f8/f16
  • complex64/complex128/complex256 復數,類型代碼 c8/c16/c32
  • bool 布爾類型 ,類型代碼 ?
  • object Python對象類型,類型代碼 O
  • string_ 固定長度的字符串類型(每個字符一個字節),類型代碼 S 。例如,要創建一個長度為10的字符串,應使用S10
  • unicode 固定長度的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 絕對值。對於非復數,可以使用更快的fabs
  • sqrt/square/exp/log/log10/log2/log1p 平方根/平方/指數/自然對數/底數為10的log/底數為2的log
  • sign 返回元素的符號: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 求和,平均數,標准差,方差,最大值,最小值,最大最小元素的索引

不聚合,產生一個由中間結果組成的數組:
- cumsumcumprod 所有元素的累積和/累計積

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.savenp.load
文本文件: np.loadtxtnp.savetxt

6. 線性代數

常用numpy.linalg函數

  • dot 矩陣乘法。兩個一維數組計算點乘,兩個多維數組計算叉乘
  • diag 返回矩陣對角線元素
  • trace 對角線元素和
  • det 行列式
  • eig 特征值、特征向量
  • inv
  • qr QR分解
  • svd 奇異值分解
  • solve 解線性方程Ax=b
  • lstsq 計算Ax=b的最小二乘解

7. 隨機數生成

生成隨機數的方法:


  • rand 均勻分布的樣本值
  • randint 給定上下限的隨機整數
  • randn 標准正態分布
  • binomial 二項分布
  • normal 正態分布
  • chisquare 卡方分布
  • gamma Gamma分布
  • uniform [0,1]之間的均勻分布




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM