import numpy as np
# NumPy是Python中科學計算的基礎軟件包。
# 它是一個提供多了維數組對象,多種派生對象(如:掩碼數組、矩陣)以及用於快速操做數組的函數及API,
# 它包括數學、邏輯、數組形狀變換、排序、選擇、I/O 、離散傅立葉變換、基本線性代數、基本統計運算、隨機模擬等等。
# NumPy包的核心是ndarray對象。
# 它封裝了python原生的同數據類型的n維數組,爲了保證其性能優良,其中有許多操做都是代碼在本地進行編譯後執行的。
# NumPy數組 和 標準Python Array(數組) 之間 的區別
# NumPy數組在建立時具備固定的大小,與Python的原生數組對象(能夠動態增加)不一樣。 更改ndarray的大小將建立一個新數組並刪除原來的數組。
# NumPy數組中的元素都須要具備相同的數據類型,所以在內存中的大小相同。 例外狀況:Python的原生數組裏包含了NumPy的對象的時候,
# 這種狀況下就容許不一樣大小元素的數組。
# 安裝
# python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose
# NumPy的主要對象是同類型的多維數組。它是一張表,全部元素(一般是數字)的類型都相同,並經過正整數元組索引。在NumPy中,維度稱爲軸。
# 軸的數目爲rank。
# [1, 2, 1] 是rank爲1的數組,由於它具備一個軸。該軸的長度爲3
t1 = [[ 1., 0., 0.],
[ 0., 1., 2.]]
# t1 有兩個軸 第一個軸(維度)的長度爲2,第二個軸(維度)的長度爲3。
# 主要屬性
# ndarray.ndim:數組的軸(維度)的個數。在Python世界中,維度的數量被稱爲rank。
# ndarray.shape:數組的維度。這是一個整數的元組,表示每一個維度中數組的大小。對於有n行和m列的矩陣,shape將是(n,m)。所以,
# shape元組的長度就是rank或維度的個數 ndim。
# ndarray.size:數組元素的總數。這等於shape的元素的乘積。
# ndarray.dtype:一個描述數組中元素類型的對象。可使用標準的Python類型建立或指定dtype。另外NumPy提供它本身的類型。
# 例如numpy.int3二、numpy.int16和numpy.float64。
# ndarray.itemsize:數組中每一個元素的字節大小。例如,元素爲 float64 類型的數組的 itemsize 爲8(=64/8),而 complex32 類型的數組的
# itemsize 爲4(=32/8)。它等於 ndarray.dtype.itemsize 。
# ndarray.data:該緩衝區包含數組的實際元素。一般,咱們不須要使用此屬性,由於咱們將使用索引訪問數組中的元素。
# 建立數組
# 1. 用普通的python列表建立數組
a1 = np.array([1,2,3])
print(a1.ndim)
print(a1.dtype)
print(a1.size)
print(a1.shape)
a1
a2 = a1 = np.array([[1,2,3], [3,4,5]], dtype='int')
a2
print(a2.ndim)
print(a2.dtype)
print(a2.size)
print(a2.shape)
# 用 nunpy 內置的方法來建立數組
#np.zeros(shape, dtype=None, order='C')
#建立shape是3x5的全1(默認浮點型)數組
a3= np.zeros((3,5), order='C')
a3
#np.zeros(shape, dtype=None, order='C')
#建立shape是3x5的全1(默認浮點型)數組
a4 = np.ones((3,5))
a4
#np.eye(N, M=None, k=0, dtype=<class 'float'>, order='C')
#建立一個形狀爲 N x N 的單位矩陣(二維數組)
a5 = np.eye(3)
a5
#empty(shape, dtype=float, order='C')
#建立一個形狀爲shape的未初始化數組,值爲隨機值
a6 =np.empty(5, dtype='int')
a7 = np.empty((3,4))
a7
#np.full(shape, fill_value, dtype=None, order='C')
#建立shape是3x5的(默認浮點型)數組,值fill_value都是3.14
a7 = np.full((3,5),5)
a7
# 使用 arange 來建立
# arange([start,] stop[, step,], dtype=None)
a8 = np.arange(0,20,5)
a8
# 使用linspace 來建立
# np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
a9= np.linspace(10,20,6)
a9
# reshape
a10 = a9.reshape(2,3)
a10
# 形狀 和操做
aa = np.arange(20).reshape(4,5)
aa
print(aa.shape)
print(aa.size)
aa.reshape(5,4) # 不改變數組自己
aa
aa.ravel() # 不改變數組自己
aa
aa
aa.resize(5,4) # 改變數組自己
aa
aa.reshape(5,-1) #reshape操做中將維度指定爲-1,則會自動計算其餘維度
# 將不一樣的數組堆疊在一塊兒
aa = np.floor(10*np.random.random((2,2)))
aa
bb = np.floor(10*np.random.random((2,2)))
bb
xx = np.vstack((aa,bb))
xx
np.hstack((aa, bb))
# numpy 切片和索引
a = np.arange(10)
a
s = slice(2,7,2)
print(a[s])
b = a[2:7:2]
b
aa = np.floor(10*np.random.random((2,12)))
aa
aa
np.hsplit(aa,3) # 平均分紅3份
np.hsplit(aa,(3,4)) # 0-3 3-4 4-
# 分割
aa = np.random.randint(1, 50,size=(7,7))
aa
# np.split(arr,index,axis)
# arr 爲被切分的數組
# index(整數或者數組)
# 若是是一個整數 就把當前數組平均分紅index份,若是數組的size不能被index整除則報錯,
# 若是爲一個數組,則沿的數組的軸線進行切分,好比:[2, 3] 則會被切割成[:2],[2:3],[3:]
# axis 爲切分的方向 默認爲0 橫向 1爲豎向
np.split(aa, [2,4,6], axis=1)
aa
aa[5]
aa[5,3]
aa[5:]
aa[:,1:2]
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
print("-----------------")
print (a[...,1]) # 第2列元素
print("-----------------")
print (a[1,...]) # 第2行元素
print("-----------------")
print (a[...,1:]) # 第2列及剩下的全部元素
# 三個點( ... )表示產生完整索引元組所需的冒號。例如,若是 x 是rank爲的5數組(即,它具備5個軸),則
# x[1,2,...] 等於 x[1,2,:,:,:]。
# x[...,3] 等效於 x[:,:,:,:,3]。
# 整數數組索引
# 實例獲取數組中(0,0),(1,1)和(2,0)位置處的元素。
x = np.array([[1, 2], [3, 4], [5, 6]])
print(x)
print('--------------')
y = x[[0,1,2], [0,1,0]]
print (y)
#獲取了 4X3 數組中的四個角的元素。 行索引是 [0,0] 和 [3,3],而列索引是 [0,2] 和 [0,2]。
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print ('咱們的數組是:' )
print (x)
print ('\n')
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
print ('這個數組的四個角元素是:')
print (y)
# 布爾索引
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print ('咱們的數組是:')
print (x)
print ('\n')
# 如今咱們會打印出大於 5 的元素
print ('大於 5 的元素是:')
print(x>5)
print (x[x > 5])
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print (a[~np.isnan(a)])
np.nan == np.nan
# 花式索引
# 花式索引指的是利用整數數組進行索引。
# 花式索引根據索引數組的值做爲目標數組的某個軸的下標來取值。對於使用一維整型數組做爲索引,若是目標是一維數組,
# 那麼索引的結果就是對應位置的元素;若是目標是二維數組,那麼就是對應下標的行。
# 花式索引跟切片不同,它老是將數據複製到新數組中。
# 一、傳入順序索引數組
x=np.arange(32).reshape((8,4))
print(x)
print('--------------------')
print (x[[4,2,1,7]])
x=np.arange(32).reshape((8,4))
print (x[[-4,-2,-1,-7]])
print (x[([1,5,7,2],[0,3,1,2])])
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
x = np.array([[1,2],[3,4],[5,6]])
print(x)
print('-----------')
print(x[[0,1]])
print('-------------')
print(x[[0,1],[0,1]])
print('------------------')
# 使用numpy.ix_()函數加強可讀性
print (x[np.ix_([0,1],[0,1])])
print('--------------')
x[[0,1],[0,1]] = [0,0]
print(x) # [[0,2],[3,0],[5,6]]
# 迭代數組
# 迭代
a = np.arange(6).reshape(2,3)
print ('原始數組是:')
print (a)
print ('\n')
print ('迭代輸出元素:')
for x in np.nditer(a):
print (x, end=", " )
print ('\n')
# for x in np.nditer(a, order='F'):Fortran order,便是列序優先;
# for x in np.nditer(a.T, order='C'):C order,便是行序優先;
a = np.arange(6).reshape(2,3)
print(a)
print('------------')
print(a.T)
for x in np.nditer(a, order ='C'):
print (x, end=", " )
print ('\n')
for i in a:
print(i)
# 修改數組中元素的值
# nditer 對象有另外一個可選參數 op_flags。 默認狀況下,nditer 將視待迭代遍歷的數組爲只讀對象(read-only),爲了在遍歷數組的同時,
# 實現對數組元素值得修改,必須指定 read-write 或者 write-only 的模式。
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始數組是:')
print (a)
print ('\n')
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改後的數組是:')
print (a)
# numpy.ndarray.flat 是一個數組元素迭代器,實例以下:
a = np.arange(9).reshape(3,3)
print ('原始數組:')
for row in a:
print (row)
#對數組中每一個元素都進行處理,可使用flat屬性,該屬性是一個數組元素迭代器:
print ('迭代後的數組:')
for element in a.flat:
print (element)
# 數組操做
# numpy.ndarray.flatten 返回一份數組拷貝,對拷貝所作的修改不會影響原始數組,格式以下:
# ndarray.flatten(order='C')
# order:'C' -- 按行,'F' -- 按列,'A' -- 原順序,'K' -- 元素在內存中的出現順序。
a = np.arange(8).reshape(2,4)
print ('原數組:')
print (a)
print ('\n')
# 默認按行
print ('展開的數組:')
print (a.flatten())
print ('\n')
print ('以 F 風格順序展開的數組:')
print (a.flatten(order = 'F'))
# 翻轉數組
# numpy.transpose 函數用於對換數組的維度 numpy.ndarray.T 相似 numpy.transpose
a = np.arange(12).reshape(3,4)
print ('原數組:')
print (a )
print ('\n')
print ('對換數組:')
print (np.transpose(a))
print('-------------------')
print(a.T)
# 軸的理解
a = np.array([[78, 34, 87, 25, 83], [25, 67, 97, 22, 13], [78, 43, 87, 45, 89]])
print(a)
print('-------------------')
print(a.max(axis=0))
print(a.max(axis=1))
#axis=0就是豎軸的數據 axis=1就是橫軸的
a = np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]])
print(a.shape)
print(a)
print('--------------')
print(a.max(axis=0))
print('-----------')
print(a.max(axis=1))
print('-------------')
print(a.max(axis=2))
# 這裏的最大值就是把一個一維數組當成了一個元素
# numpy.rollaxis 函數向後滾動特定的軸到一個特定位置
# numpy.rollaxis(arr, axis, start)
# arr:數組
# axis:要向後滾動的軸,其它軸的相對位置不會改變
# start:默認爲零,表示完整的滾動。會滾動到特定位置。
# 建立了三維的 ndarray
a = np.arange(8).reshape(2,2,2)
print ('原數組:')
print (a)
print ('\n')
# 將軸 2 滾動到軸 0(寬度到深度)
# 程序運行np.rollaxis(a, 2)時,講軸2滾動到了軸0前面,其餘軸相對2軸位置不變(start默認0),數組下標排序由0,1,2變成了1,2,0
print ('調用 rollaxis 函數:')
print (np.rollaxis(a,2))
# 將軸 0 滾動到軸 1:(寬度到高度)
print ('\n')
print ('調用 rollaxis 函數:')
print (np.rollaxis(a,2,1))
# numpy.swapaxes 函數用於交換數組的兩個軸 numpy.swapaxes(arr, axis1, axis2)
# arr:輸入的數組
# axis1:對應第一個軸的整數
# axis2:對應第二個軸的整數
# 建立了三維的 ndarray
a = np.arange(8).reshape(2,2,2)
print ('原數組:')
print (a)
print ('\n')
# 如今交換軸 0(深度方向)到軸 2(寬度方向)
print ('調用 swapaxes 函數後的數組:')
print (np.swapaxes(a, 2, 0))
# 隨機數組
# 隨機建立 指定形狀的數組 0-1之間的數
np.random.rand(5)
np.random.rand(5,5, 5)
# 隨機獲取指定範圍的一個數
np.random.uniform(0,100)
# 隨機獲取指定範圍的一個整數
np.random.randint(0,52)
np.random.randint(0,20,size=(3,4))
np.random.randint(0,20,size=(5,4))
# np.random.choice(F,N,P)
# 從0-F範圍裏面去N個數(不包含N),P表示機率
np.random.choice(2,2)
a1 = np.random.choice(5,3,p=[0.2,0,0.5,0.3,0])
a1
b = np.random.randint(0,20,size=(5,4))
print(b)
np.random.shuffle(b)
print(b)
# 計算
a = [1,2,3,4]
b= np.array(a,dtype='float')
b
b+1
b
a = np.array([1,3,5,7])
a
# 同緯度且個數相同的數組相加
a+b
# 數組a中大於3的數就會顯示True小於3的數就會顯示False
a[a>3]
print(a)
a[a>3]
c = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
c
# 求出c中大於5且爲偶數的元素
c[(c>5) & (c%2==0)]
d=np.array([1.1,2.2,3.3,4.4,5.5,6.6,7.7])
d
# 向上取整
print(np.ceil(d))
# 向下取整
print(np.floor(d))
# 絕對值
print(np.abs(d))
# 開方
print(np.sqrt(b))
# 分別去除小數部分和整數部分
print('------------------')
print(np.modf(d))
# e爲底的指數函數
print(np.exp(d))
print(np.log(d))
# 四捨五入
print(np.round(d))
print('------------------')
print(np.rint(d))
# 向0取整
print(np.trunc(d))
# 是否不等於任何整數
print(np.isnan(d))
#
print(np.cos(b))
print(np.sin(b))
print(np.tan(b))
# 上述操做 對普通列表 也實用
print(d)
print('-------------------------')
# 求和
print(d.sum())
# 平均值
print(d.mean())
# 等差數列
print(d.cumsum())
# 標準差
print(d.std())
# 方差
print(d.var())
# 最小值
print(d.min())
#最大值
print(d.max())
print('---------------')
# 最大值索引
print(d.argmin())
# 最小值索引
print(d.argmax())
a = np.array( [20,30,40,50] )
b = np.arange( 4 )
print(a)
print('-----')
print(b)
c = a-b
c
b**2
10*np.sin(a)
# 與許多矩陣語言不一樣,乘法運算符 * 的運算在NumPy數組中是元素級別的。矩陣乘積可使用 dot 函數或方法執行
a = np.array( [[1,1,1],[0,1,1]] )
a
b = np.array( [[2,0], [3,4], [1,1] ])
b
a*b
a.dot(b)
a = np.ones((2,3), dtype=int)
a
a*=3
a
b = np.random.randint(0,6, size=(2,3))
b
b+=a
b
print(a)
print(b)
a+=b
a
# 複製和視圖
# NumPy中,數組的複製有三種方式:
# Python通用的地址複製:經過 b = a 複製 a 的值,b 與 a 指向同一地址,改變 b 同時也改變 a。
# 經過視圖ndarray.view()僅複製值,當對 c 值進行改變會改變 a 的對應的值,而改變 c 的 shape 不改變 a 的 shape。
# ndarray.copy() 進行的完整的拷貝,產生一份徹底相同的獨立的複製。
a = np.arange(12)
a
b=a
a is b
c = a.view()
c
a is c
c.shape = 2,6
c
c [0,0] = 55
a
d = a.copy()
d is a
d
d.shape = 2,6
d
d[1,1] = 22
a