Python 模塊之科學計算 Numpy

numPy、Scipy、pandasmatplotlib簡介

  1. numpy——基礎,以矩陣爲基礎的數學計算模塊,純數學存儲和處理大型矩陣。  這個是很基礎的擴展,其餘的擴展都是以此爲基礎。
  2. scipy——數值計算庫,在numPy庫的基礎上增加了衆多的數學、科學以及工程計算中常用的庫函數。  方便、易於使用、專爲科學和工程設計的Python工具包.它包括統計,優化,整合,線性代數模塊,傅里葉變換,信號和圖像處理,常微分方程求解器等等。
  3. pandas——數據分析,基於numPy 的一種工具,爲了解決數據分析任務而創建的.Pandas 納入了大量庫和一些標準的數據模型,提供了高效地操作大型數據集所需的工具。
  4. matplotlib——繪圖,對於圖像美化方面比較完善,可以自定義線條的顏色和式樣,可以在一張繪圖紙上繪製多張小圖,也可在一張圖上繪製多條線,可以很方便的對數據進行可視化分析。

Numpy發展歷史

  1. 1995年 Jim HugUNin開發了Numeric。
  2. 隨後,Numarray包誕生。
  3. Travis Oliphants整合Numeric和Numarray,開發Numpy,於2006年發佈第一個版本。
  4. Numpy(Numeric Python)提供了許多高級的數值編程工具,如:矩陣數據類型、矢量處理,以及精密的運算庫。專爲進行嚴格的數字處理而產生。多爲很多大型金融公司使用,以及核心的科學計算組織如:Lawrence Livermore,NASA用其處理一些本來使用C++,Fortran或Matlab等所做的任務。
  5. 使用Anaconda發行版的Python,已經幫我們事先安裝好了Numpy模塊,因此無需另外安裝。
  6. 依照標準的Numpy約定,習慣使用 import numpy as np方式導入該模塊。

NumPy模塊

numPyNumerical Python,即數值Python包,是Python進行科學計算的一個基礎包,所以是一個掌握其他Scipy庫中模塊的基礎模塊,一定需要先掌握該包的主要使用方式。

官網:http://www.numpy.org/

官方文檔:https://docs.scipy.org/doc/numpy/user/index.html

NumPy核心數據結構:ndarray

NumPy的數組類被稱作ndarray。通常被稱作數組。注意numpy.array和標準Python庫類array.array並不相同,後者只處理一維數組和提供少量功能。

一種由相同類型的元素組成的多維數組,元素數量是實現給定好的

元素的數據類型由dtype(data-type)對象來指定,每個ndarray只有一種dtype類型

ndarray的大小固定,創建好數組後數組大小是不會再發生改變的

ndarray創建

函數創建

array:接收一個普通的python序列,並將其轉換爲ndarray

print(np.array([1,2,3]))    # 用列表創建一維數組
print(np.array((1,2,3)))    # 用元組創建一維數組
print(np.array([[1,2,3],[3,4,5]])) 	# 創建二維數組
print(np.array([[[1,2,3],[3,4,5]], [[4,5,6],[7,8,9]]]))  # 創建三維數組

# [1 2 3]

# [1 2 3]  
		
# [[1 2 3]
# [3 4 5]] 

# [[[1 2 3]
# [3 4 5]]
# [[4 5 6]
# [7 8 9]]]

zeros函數:創建指定長度或者形狀的全零數組

print(np.zeros((3,4)))

# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]]

ones函數:創建指定長度或者形狀的全1數組。

print(np.ones((3,4)))

# [[1. 1. 1. 1.]
# [1. 1. 1. 1.]
# [1. 1. 1. 1.]]

empty函數:創建一個沒有任何具體值的數組(準備地說是創建一些未初始化的ndarray多維數組)

print(np.empty((3,4)))

# [[6.23042070e-307 3.56043053e-307 1.37961641e-306 6.23039354e-307]
#  [6.23053954e-307 9.34609790e-307 8.45593934e-307 9.34600963e-307]
#  [1.86921143e-306 6.23061763e-307 9.34608432e-307 4.24399158e-314]]

其他方式:

arange函數: 類似python的range函數,通過指定開始值、終值和步長來創建一個一維數組,注意:最終創建的數組不包含終值

print(np.arange(9))      # 一個參數時代表是n值
print(np.arange(0,9,3))  # 起始值,終值,步長

linspace函數:通過指定開始值、終值和元素個數來創建一個一維數組,數組的數據元素符合等差數列,可以通過endpoint關鍵字指定是否包含終值,默認包含終值

print(np.linspace(0,8,5)) # 形成一個0到8之間的等差數列,共5個元素
# [0. 2. 4. 6. 8.]

logspace函數:和linspace函數類似,不過創建的是等比數列數組

print(np.logspace(0, 2, 5))  # 範圍1-10**2,5個元素
print(np.logspace(0, 5, 6, base=2))  # 範圍 1-2**5,6個元素,base是底

# [  1.           3.16227766  10.          31.6227766  100.        ]
# [ 1.  2.  4.  8. 16. 32.]

np.random.randint((m,n,size=(a,b))):創建隨機整數數組,選值的範圍是[m,n); a是數組的行;b是數組的列數

print(np.random.randint(1,9, size=(3,4)))

# [[1 2 3 5]
#  [1 6 2 7]
#  [8 6 4 6]]

np.random.random((m,n,p)):創建隨機數組,範圍0-1之間,m爲維數,默認爲1; n爲行數,默認爲1; p爲列數,默認爲1

print(np.random.random())
print(np.random.random((3,3)))
print(np.random.random((3,4,5)))

0.488869811358302

[[0.04233258 0.3131225  0.68944938]
 [0.87059721 0.67384851 0.15279566]
 [0.55984723 0.93180875 0.94961102]]

[[[0.59919237 0.1994035  0.51349683 0.74415431 0.08967972]
  [0.51202792 0.90590204 0.72763875 0.28438195 0.74681998]
  [0.83841345 0.58347337 0.11484284 0.55444849 0.7978348 ]
  [0.28018216 0.01040884 0.57392768 0.2434304  0.59227622]]
 [[0.5430919  0.42146133 0.14726534 0.03191174 0.26208523]
  [0.09970413 0.42386556 0.91181302 0.98131496 0.80365805]
  [0.45376739 0.83388326 0.44127547 0.09819375 0.7977529 ]
  [0.94739682 0.70020476 0.21155345 0.42489893 0.99906962]]
 [[0.91776003 0.10385849 0.52768841 0.79937635 0.69065729]
  [0.00796977 0.77475184 0.37661829 0.86323215 0.48432327]
  [0.26268683 0.51724413 0.24022605 0.08388501 0.30099232]
  [0.09245234 0.07751062 0.77418801 0.43640313 0.99036787]]]

 np.random.randn(m,n):創建一個標準正態分佈的數組,m表示行數;n表示列數。

print(np.random.randn(3,2))
# [[ 0.10110133 -0.23799349]
#  [ 0.44611654  2.52476781]
#  [-0.52620207 -1.42422191]]

ndarray對象屬性

  • ndim 數組軸(維度)的個數,軸的個數被稱作秩
  • shape 數組的維度, 例如一個2排3列的矩陣,它的shape屬性將是(2,3),這個元組的長度顯然是秩,即維度或者ndim屬性
  • size 數組元素的總個數,等於shape屬性中元組元素的乘積。
  • dtype 一個用來描述數組中元素類型的對象,可以通過創造或指定dtype使用標準Python類型。不過NumPy提供它自己的數據類型。
  • itemsize 數組中每個元素的字節大小。例如,一個元素類型爲float64的數組itemsiz屬性值爲8(=64/8),又如,一個元素類型爲complex32的數組item屬性爲4(=32/8).
arr = np.random.randint(1, 9, size=(3,3))
print(arr.ndim)       # 2
print(arr.shape)      # (3, 3)
print(arr.dtype)      # int32
print(arr.size)       # 9
print(arr.itemsize)   # 4

NumPy基本數據類型

數據類型

類型簡 寫

說明

int_

 

默認整形

intc

 

等價於long的整形

int8

i1

字節整形,1個字節,範圍:[-128,127]

int16

i2

整形,2個字節,範圍:[-32768,32767]

int32

i3

整形,4個字節,範圍:[-2^31, 2^31-1]

int64

i4

整形,8個字節,範圍:[-2^63, 2^63-1]

uint8

u1

無符號整形, 1個字節, 範圍:[0,255]

uint16

u2

無符號整形, 2個字節, 範圍:[0,65535]

uint32

u3

無符號整形, 1個字節, 範圍:[0, 2^32-1]

uint64

u4

無符號整形, 1個字節, 範圍:[0,2^64-1]

bool_

 

以一個字節形成存儲的布爾值(True或者False)

float_

 

float64簡寫形式

float16

f2

半精度浮點型(2字節)1符號位+5位指數+10位的小數部分

float32

f4或者f

單精度浮點型(4字節)1符號位+8位指數+23位的小數部分

float64

f8或者d

雙精度浮點型(8字節)1符號位+11位指數+52位的小數部分

complex_

c16

complex128的簡寫形式

complex64

c8

複數,由兩個32位的浮點數來表示

complex128

c16

複數,由兩個64位的浮點數來表示

object

O

Python對象類型

String_

S

固定長度的字符串類型(每個字符1個字節),比如:要創建一個長度爲8的字符串,應該使用S8

Unicode_

U

固定長度的unicode類型的字符串(每個字符佔用字節數由平臺決定),長度定義類似String_類型

ndarray修改類型

創建numpy數組的時候可以通過屬性dtype顯示指定數據類型,如果不指定的情況下,numpy會自動推斷出適合的數據類型,所以一般不需要顯示給定數據類型。

 如果需要更改一個已經存在的數組的數據類型,可以通過astype方法進行修改從而得到一個新數組

arr = np.random.randint(1, 9, size=(3,3))
print(arr.dtype)          # int32
arr2 = arr.astype(float)
print(arr2.dtype)         # float64

數值型dtype的命名方式爲:一個類型名稱(eg:int、float等),後接一個表示各個元素位長的數字。比如Python的float數據類型(雙精度浮點值),需要佔用8個字節(64位),因此在NumPy中記爲float64。每個數據類型都有一個類型代碼,即簡寫方式

arr3 = np.random.randint(1, 9, size=(3,3), dtype='i8')
print(arr3.dtype) # int64

ndarray修改形狀

對於一個已經存在的ndarray數組對象而言,可以通過修改形狀相關的參數/方法從而改變數組的形狀。

直接修改數組ndarray的shape值, 要求修改後乘積不變。

直接使用reshape函數創建一個改變尺寸的新數組,原數組的shape保持不變,但是新數組和原數組共享一個內存空間,也就是修改任何一個數組中的值都會對另外一個產生影響,另外要求新數組的元素個數和原數組一致。

當指定某一個軸爲-1的時候,表示將根據數組元素的數量自動計算該軸的長度值。

arr = np.array([1,2,3,4,5,6,7,8])
print(arr.reshape(2,4))
arr = np.array([1,2,3,4,5,6,7,8])
print(arr.reshape(2,-1))

# [[1 2 3 4]
#  [5 6 7 8]]
# [[1 2 3 4]
#  [5 6 7 8]]

NumPy基本操作

數組與標量、數組之間的運算

數組不用循環即可對每個元素執行批量的算術運算操作,這個過程叫做矢量化,即用數組表達式代替循環的做法。

矢量化數組運算性能比純Python方式快上一兩個數據級。

大小相等的兩個數組之間的任何算術運算都會將其運算應用到元素級上的操作。

元素級操作:在NumPy中,大小相等的數組之間的運算,爲元素級運算,即只用於位置相同的元素之間,所得的運算結果組成一個新的數組,運算結果的位置跟操作數位置相同。

# 數組和標量運算
arr1 = np.array((1,2,3,4,5))
print(arr1+2)   # [3 4 5 6 7]
print(arr1-3)   # [-2 -1  0  1  2]
print(arr1*2)   # [ 2  4  6  8 10]
print(arr1/2)   # [0.5 1.  1.5 2.  2.5]
print(arr1**2)  # [ 1  4  9 16 25]
print(2**arr1)  # [ 2  4  8 16 32]
# 數組和數組運算
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
arr3 = np.array([[10, 20, 30], [40, 50, 60]])
print(arr2+arr3)  # 相乘的兩者結構相同
print(arr2*arr3)
print(arr2**arr3)

# [[11 22 33]
#  [44 55 66]]
# [[ 10  40  90]
#  [160 250 360]]
# [[          1     1048576 -1010140999]
#  [          0  1296002393           0]]

數組的矩陣積(matrix product)

矩陣積(matrix product):兩個二維矩陣(行和列的矩陣)滿足第一個矩陣的列數與第二個矩陣的行數相同,那麼可以進行矩陣的乘法,即矩陣積,矩陣積不是元素級的運算。也稱爲點積、數量積。

arr1 = np.array((
    (1, 2, 3),
    (4, 5, 6),
    (7, 8, 9)))
arr2 = np.array((
    (1, 2),
    (3, 4),
    (5, 6)))
print(np.dot(arr1,arr2))
print(arr1.dot(arr2))

# [[ 22  28]
#  [ 49  64]
#  [ 76 100]]

# [[ 22  28]
#  [ 49  64]
#  [ 76 100]]

數組的索引與切片

ndarray-多維數組的索引

根據數組的形狀,進行索引

arr2 = np.arange(27).reshape(3, 3, 3)
print(arr2)
print(arr2[0])  # 一維索引
print(arr2[0][1])  # 一維,二維
print(arr2[0][1][2])  # 一維,二維,三維
print(arr2[0, 1, 2])  # 推薦寫法

# [[[ 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]]]

# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]

# [3 4 5]

# 5

# 5

切片

在各維度上單獨切片,如果某維度數據都保留,直接使用冒號,不指定起始值和終值

從Numpy切片得到的數組,只是原來數組的一個視圖,內部數據使用相同的存儲地址,所以對切片得到的數組修改會影響原數組

print(arr2[0:2, 1, :])

# [[ 3  4  5]
#  [12 13 14]]

布爾類型索引

利用布爾類型的數組進行數據索引,最終返回的結果是對應索引數組中數據爲True位置的值。

ndarray-花式索引

花式索引(Fancy indexing)指的是利用整數數組進行索引的方式

數組的轉置與軸對換

數組轉置是指將shape進行重置操作,並將其值重置爲原始shape元組的倒置,比如原始的shape值爲:(2,3,4),那麼轉置後的新元組的shape的值爲: (4,3,2)f

對於二維數組而言(矩陣)數組的轉置其實就是矩陣的轉置

可以通過調用數組的transpose函數或者T屬性進行數組轉置操作

arr1 = np.arange(20).reshape(5,-1)
print(arr1)
arr2 = arr1.transpose()
print(arr2)
arr3 = arr1.T
print(arr3)

#################
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]
 [16 17 18 19]]
#################
[[ 0  4  8 12 16]
 [ 1  5  9 13 17]
 [ 2  6 10 14 18]
 [ 3  7 11 15 19]]
#################
[[ 0  4  8 12 16]
 [ 1  5  9 13 17]
 [ 2  6 10 14 18]
 [ 3  7 11 15 19]]

通用函數:快速的元素級數組成函數

ufunc:numpy模塊中對ndarray中數據進行快速元素級運算的函數,也可以看做是簡單的函數(接受一個或多個標量值,併產生一個或多個標量值)的矢量化包裝器。

主要包括一元函數和二元函數

ndarray-通用函數/常用函數(一元函數)

一元ufunc

描述

調用方式

abs, fabs

計算整數、浮點數或者複數的絕對值,對於非複數,可以使用更快的fabs

np.abs(arr)

np.fabs(arr)

sqrt

計算各個元素的平方根,相當於arr ** 0.5, 要求arr的每個元素必須是非負數

np.sqrt(arr)

square

計算各個元素的評分,相當於arr ** 2

np.square(arr)

exp

計算各個元素的指數ex次方

np.exp(arr)

loglog10

log2log1p

分別計算自然對數、底數爲10log、底數爲2log以及log(1+x);要求arr中的每個元素必須爲正數

np.log(arr)

np.log10(arr)

np.log2(arr)

np.log1p(arr)

sign

計算各個元素的正負號: 1 正數,0:零,-1:負數

np.sign(arr)

ceil

計算各個元素的ceiling值,即大於等於該值的最小整數

np.ceil(arr)

floor

計算各個元素的floor值,即小於等於該值的最大整數

np.floor(arr)

rint

將各個元素值四捨五入到最接近的整數,保留dtype的類型

np.rint(arr)

modf

將數組中元素的小數位和整數位以兩部分獨立數組的形式返回

np.modf(arr)

isnan

返回一個表示那些值是NaN(不是一個數字)”的布爾類型數組

np.isnan(arr)

isfiniteisinf

分別一個表示那些元素是有窮的(inf、非NaN)”或者那些元素是無窮的的布爾型數組

np.isfinite(arr)

np.isinf(arr)

coscoshsin

sinhtantanh

普通以及雙曲型三角函數

np.cos(arr)

np.sin(arr)

np.tan(arr)

arccosarccosh

arcsin、arcsinh、

arctanarctanh

反三角函數

np.arccos(arr)

np.arrsin(arr)

np.arrtan(arr)

ndarray-通用函數/常用函數(二元函數)

二元ufunc

描述

調用方式

mod

元素級的取模

np.mod(arr1,arr2)

dot

求兩個數組的點積

np.dot(arr1,arr2)

greatergreater_equalless

less_equalequalnot_equal

執行元素級別的比較運算,最終返回一個布爾型數組

np.greater(arr1, arr2)

np.less(arr1, arr2)

np.equal(arr1, arr2)

logical_andlogical_or

logical_xor

執行元素級別的布爾邏輯運算,相當於中綴運算符&|^

np.logical_and(arr1,arr2)

np.logical_or(arr1,arr2)

np.logical_xor(arr1,arr2)

power

求解對數組中的每個元素進行給定次數的指數值,類似於: arr ** 3

np.power(arr, 3)

聚合函數

聚合函數是對一組值(eg一個數組)進行操作,返回一個單一值作爲結果的函數。當然聚合函數也可以指定對某個具體的軸進行數據聚合操作;常將的聚合操作有:平均值、最大值、最小值、方差等等

當axis=0表示列;axis=1表示行,不寫代表計算整個矩陣的

arr = np.array([[1, 5, 7, 4], [0, 6, 3, 8], [2, 6, 9, 7]])
print(arr)
print('arr的最小值是:', arr.min())
print('arr的最大值是:', arr.max())
print('arr的平均值是:', arr.mean())
print('arr的標準差差是:', arr.std())
print('arr的方差是:', np.power(arr.std(),2))
print('arr中每一列的最小值是:', arr.min(axis=0))  # 當axis=0表示列;axis=1表示行
print('arr中每一列的最大值是:', arr.max(axis=0))
print('arr中每一列的平均值是:', arr.mean(axis=0))
print('arr中每一行的最小值是:', arr.min(axis=1))
print('arr中每一行的最大值是:', arr.max(axis=1))
print('arr中每一行的平均值是:', arr.mean(axis=1))

###############################################################################
[[1 5 7 4]
 [0 6 3 8]
 [2 6 9 7]]
arr的最小值是: 0
arr的最大值是: 9
arr的平均值是: 4.833333333333333
arr的標準差差是: 2.733536577809454
arr的方差是: 7.472222222222221
arr中每一列的最小值是: [0 5 3 4]
arr中每一列的最大值是: [2 6 9 8]
arr中每一列的平均值是: [1.         5.66666667 6.33333333 6.33333333]
arr中每一行的最小值是: [1 0 2]
arr中每一行的最大值是: [7 8 9]
arr中每一行的平均值是: [4.25 4.25 6.  ]

np.where函數

np.where函數是三元表達式x if condition else y的矢量化版本

arr1 = np.array([-1.1,-1.2,-1.3,-1.4,-1.5])
arr2 = np.array([-2.1,-2.2,-2.3,-2.4,-2.5])
condition = (arr1<arr2)
result1 = [x if c else y for (x,y,c) in zip(arr1, arr2, condition)]  # 用於一維數組,不能用於多維
result2 = np.where(condition, arr1, arr2)  # 適合任何維度
print('使用python語法,結果爲:', result1,';數據類型爲:', type(result1))
print('使用np.where語法,結果爲:', result2,';數據類型爲:', type(result2))

# 使用python語法,結果爲: [-2.1, -2.2, -2.3, -2.4, -2.5] ;數據類型爲: <class 'list'>
# 使用np.where語法,結果爲: [-2.1 -2.2 -2.3 -2.4 -2.5] ;數據類型爲: <class 'numpy.ndarray'>

將數組中的所有異常數字替換爲0,比如將NaN替換爲0

arr3 = np.array([
[1, 2, np.nan, 4],
[4, 5, 6, np.nan],
[7, 8, 9, np.inf],
[np.inf, np.e, np.pi, 4]
])
condition = np.isnan(arr3)|np.isinf(arr3)
print(arr3)
print(np.where(condition, 0, arr3))

##############################################################3
[[1.         2.                nan 4.        ]
 [4.         5.         6.                nan]
 [7.         8.         9.                inf]
 [       inf 2.71828183 3.14159265 4.        ]]
[[1.         2.         0.         4.        ]
 [4.         5.         6.         0.        ]
 [7.         8.         9.         0.        ]
 [0.         2.71828183 3.14159265 4.        ]]

np.unique函數

np.unique函數的主要作用是將數組中的元素進行去重操作(也就是隻保存不重複的數據)

arr1 = np.array(['a', 'b', 'c', 'a', 'd', 'c', 'e'])
arr2 = np.unique(arr1)
print('原始數據:', arr1)
print('去重之後的數據:', arr2)

# 原始數據: ['a' 'b' 'c' 'a' 'd' 'c' 'e']
# 去重之後的數據: ['a' 'b' 'c' 'd' 'e']

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章