一、Numpy庫與多維數組


# Author:Zhang Yuan
import numpy as np
'''重點摘錄:
軸的索引axis=i可以理解成是根據[]層數來判斷的,0表示[],1表示[[]]...
Numpy廣播的規則可理解成:結構相同,點對點;結果不同,分別匹配。[]是最小單元,按最小單元匹配。
Numpy中邏輯盡量用邏輯操作運算符&/|,少用關鍵字and/or
Numpy的向量化操作比純Python速度更快。
ndarray的基本運算 + - * /  // 等... 會調用對應的通用函數,為數組中元素的運算。
'''
#NumPy 最重要的一個特點是其 N 維數組對象 ndarray。

#ndarray對象的維度是通過多層[]來確定的。[...]表示一維數據,[[...]]表示二維數據,[[[...]]]表示三維數據...
#軸的索引axis=i是根據[]層數來判斷的,0表示[],1表示[[]]...

# [,]中的逗號,表示當前所在維度層的數據划分。[1,2,3] 一維划分。[[1, 2], [3, 4]] 外部逗號為第一層維度(行)划分,內部逗號為第二層維度(列)的划分

# int8, int16, int32, int64 四種數據類型可以使用字符串 'i1', 'i2','i4','i8' 代替

#賦值系列---------------------------------------------------------------
#原數據輸入的方式形成數組:
#原數據輸入可以是各種類型。
#"層次相同、數據個數相同"會默認轉成多維數組,也就是嚴格符合多維數組格式的會自動轉換.
print(np.array([1,2,[3]]))  #[1 2 list([3])],只有一個二層次
print(np.asarray([(1,),2,[3]]))  #[(1,) 2 list([3])],只有一個一層次
print(np.array([(1,),(2,),[3,]]))  #[[1],[2],[3]],都是二層次,轉換
print(np.asarray([(1,),(2,),(3,)]))  #[[1],[2],[3]],都是二層次,轉換
print(np.array([(1,2),(3,)]))  #[(1, 2) (3,)],都二層,但大小不同
print(np.asarray([(1,2),(3,4)]))  #[[1, 2],[3, 4]],都二層且大小相同,轉換

#創建的方式形成數組:
#以shape維度描述來創建。
print(np.zeros((3,2))) #empty(),ones()
#以buffer來創建,用於實現動態數組。
#buffer 是字符串的時候,Python3 默認 str 是 Unicode 類型,所以要轉成 bytestring 在原 str 前加上 b。
print(np.frombuffer(b'Hello World',dtype =  'S1'))
print(np.frombuffer(np.array([1,2,3,4,5]),dtype=int))
#以迭代對象來創建
print(np.fromiter(range(5),dtype=int))
#以數值范圍來創建
print(np.arange(10,20,2)) #[10  12  14  16  18]
print(np.linspace(1,10,10)) #[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
print(np.logspace(1,2,num=2)) #[ 10. 100.]
#--------------------------------------------------------------------------

#訪問系列------------------------------------------------------------------
#切片還可以包括省略號 ...,來使選擇元組的長度與數組的維度相同。如果在行位使用省略號,它將返回包含行中元素的 ndarray
#多維數組的切片和索引[,]中第一層逗號表示維度划分,第一層逗號分割的左右部分一定是按照維度順序.
#多維數組若沒有第一層逗號,會默認加上第一層逗號。但僅傳入元組逗號省略。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[...,1:]) # [[2 3],[5 6],[8 9]],相當於a[:,1:].
print(a[(1,2)])  # 6, 僅傳入元組括號省略:a[1,2]=6.
print(a[[1,2]])  # [[4 5 6],[7 8 9]], 默認加上第一層逗號,相當於a[[1,2],]
print(a[[-1,-3]]) #[[7 8 9],[1 2 3]], 默認加上第一層逗號,相當於a[[-1,-3],]
print(a[(1,2),]) # [[4 5 6],[7 8 9]],相當於a[(1,2),:],行1、2,列全部

#多維多值索引一定要一一配對,且輸出形式與輸入的索引形式相同
print(a[[0,1,2], [0,1,0]])  #[1 5 7],多值索引。一對一:0-0,1-1,2-0
print(a[ [ [0,0],[2,2] ] , [ [0,2],[0,2] ] ]) #[[1 3], [7 9]]
print(a[np.array([[1],[2]]),np.array([[0],[2]])]) #[[4], [9]]
print(a[ [[1],[2]] , [[0],[2]] ]) #[[4], [9]]

#多維多值索引各維度層次不同,會自動默認到最高層次.
#各維度表示形式相同,點對點匹配,且大小必須相同。各維度表示形式不同,以不同的形式分別匹配。
x=np.arange(12).reshape((3,4))
'''x=array([[0, 1, 2,  3],
            [4, 5, 6,  7],
            [8, 9, 10, 11]])'''
print(x[ [1,2,0] , [[[3,1,0]]] ]) #[[[7 9 0]]] 各維度表示形式相同,點對點匹配;層次不同,會自動默認到最高層次.
x1=x[ [[1],[2],[0]] , [[3,1,0]] ] #[x]配 [a,b,c,d]表示:按a,b,c,d順序索引第x行
'''x1=array([[ 7,  5,  4],
             [11,  9,  8],
             [ 3,  1,  0]]) '''

x2=x[ [[1,2,0]] , [[3],[1],[0]] ] #[a,b,c,d]配[x]表示:按a,b,c,d順序索引第x列
'''x2=array([[ 7, 11,  3],
             [ 5,  9,  1],
             [ 4,  8,  0]])'''
#其中x1、x2互為轉置矩陣

#第一維行為變獨立( array([[1],[3]]), array([[2, 5]]) )
np.ix_([1,3],[2,5])
print(x[np.ix_([1,2,0],[3,1,0])])
'''[ [ 7  5  4]
     [11  9  8]
     [ 3  1  0] ]'''

#以布爾數組np.array([True,False,...])形式可以過濾
x= np.array([1,2,3,4,5,6])
x[np.array([True,False,True,False,True,False])] #array([1, 3, 5])
x[x > 2] #array([3, 4, 5, 6])
a = np.array([np.nan,  1,2,np.nan,3,4,5])
print(a[~np.isnan(a)]) #[1. 2. 3. 4. 5.],其中 ~ 取補運算符,按位取反.
#----------------------------------------------------------------------

#當運算中的 2 個數組的形狀不同時,但要具備拉升可匹配性Broadcasting,numpy 會把數組自動拉升Broadcasting到相同,在進行元素運算

#numpy中運算函數也會遵循匹配性Broadcasting原則。

#對於一個多維數組a,如果a已經分配內存了,其轉置a.T與a共享內存,且存儲順序也是一樣的。
# 如果希望a.T與a存儲順序不同,可以需要重新分配內存:a.T.copy()。
# 或者控制遍歷順序:
# for x in np.nditer(a, order='F'):Fortran order,即是列序優先;
# for x in np.nditer(a.T, order='C'):C order,即是行序優先;

#注意numpy中緯度是:011---軸0、1、2---軸Z、Y、X,新增的緯度放入軸索引0
#一維數據:0軸-X軸;二維數據:0軸-Y軸-列數據、1軸-X軸-行數據;...

# Numpy數組操作------------------------------------------------------
# 修改數組形狀:
#     reshape    不改變數據的條件下修改形狀
#     flat    數組元素迭代器
#     flatten    返回一份數組拷貝,對拷貝所做的修改不會影響原始數組
#     ravel    返回展開數組
# 翻轉數組:
#     transpose    對換數組的維度
#     ndarray.T    和 self.transpose() 相同
#     rollaxis    向后滾動指定的軸
#     swapaxes    對換數組的兩個軸
# 修改數組維度:
#     broadcast    產生模仿廣播的對象
#     broadcast_to    將數組廣播到新形狀
#     expand_dims    擴展數組的形狀
#     squeeze    從數組的形狀中刪除一維條目
# 連接數組
#     concatenate    連接沿現有軸的數組序列
#     stack    沿着新的軸加入一系列數組。
#     hstack    水平堆疊序列中的數組(列方向)
#     vstack    豎直堆疊序列中的數組(行方向)
# 分割數組
#     split    將一個數組分割為多個子數組
#     hsplit    將一個數組水平分割為多個子數組(按列)
#     vsplit    將一個數組垂直分割為多個子數組(按行)
# 數組元素的添加與刪除
#     resize    返回指定形狀的新數組
#     append    將值添加到數組末尾
#     insert    沿指定軸將值插入到指定下標之前
#     delete    刪掉某個軸的子數組,並返回刪除后的新數組
#     unique    查找數組內的唯一元素

#使用細節:
#flat數組元素迭代器
a = np.arange(9).reshape(3,3)
for row in a:print(row) #打印行
for element in a.flat:print (element) #打印元素

#可以先定義格式,再賦值
c=np.empty((4,3))
c.flat=[i for i in range(12)]

#運算也遵循相同結構點對點,不同結構分配匹配原則
x = np.array([[7], [8], [9]])
x1= np.array([7, 8, 9])
y = np.array([4, 5, 6])
print(x+y)  #結果不同,分別運算。
print(x1+y) #結構相同,一對一運算。
print(x*y)  #結果不同,分別運算。
print(x1*y) #結構相同,一對一運算。

#numpy.swapaxes函數用於交換數組的兩個軸
#注意numpy中緯度是:011---軸0、1、2---軸Z、Y、X,新增的緯度放入軸索引0
x=np.arange(8).reshape((2,2,2))
print(x)
print (np.swapaxes(x, 0, 2))

#np.expand_dims()原理
x=np.array([1,2,3,4])
print(x)                        #[1 2 3 4]
print(np.expand_dims(x,axis=0)) #[[1 2 3 4]] 相當於在第一層[]或第零層元素上加個[]
print(np.expand_dims(x,axis=1)) #[[1],[2],[3],[4]] 相當於在第二層[]或第一層元素上加個[]
y=np.array([[1,2],[3,4]])
print(y)                        #[[1 2],[3 4]]
print(np.expand_dims(y,axis=0)) #[[[1 2],[3 4]]] 相當於在第一層[]或第零層元素上加個[]
print(np.expand_dims(y,axis=1)) #[[[1 2]], [[3 4]]] 相當於在第二層[]或第一層元素上加個[]
print(np.expand_dims(y,axis=2)) #[[[1],[2]],[[3],[4]]] 相當於在第三層[]或第二層元素上加個[]
#---------------------------------------------------------------

# NumPy 字符串函數,用於對 dtype 為 numpy.string_ 或 numpy.unicode_ 的數組執行向量化字符串操作。
#     add()    對兩個數組的逐個字符串元素進行連接
#     multiply()    返回按元素多重連接后的字符串
#     center()    居中字符串
#     capitalize()    將字符串第一個字母轉換為大寫
#     title()    將字符串的每個單詞的第一個字母轉換為大寫
#     lower()    數組元素轉換為小寫
#     upper()    數組元素轉換為大寫
#     split()    指定分隔符對字符串進行分割,並返回數組列表
#     splitlines()    返回元素中的行列表,以換行符分割
#     strip()    移除元素開頭或者結尾處的特定字符
#     join()    通過指定分隔符來連接數組中的元素
#     replace()    使用新字符串替換字符串中的所有子字符串
#     decode()    數組元素依次調用str.decode
#     encode()    數組元素依次調用str.encode

#NumPy 中包含了一個矩陣庫 numpy.matlib,該模塊中的函數返回的是一個矩陣,而不是 ndarray 對象。
#numpy.matlib庫不在init內,需要import numpy.matlib

# NumPy 提供了線性代數函數庫 linalg,該庫包含了線性代數所需的所有功能
#     dot            兩個數組的點積,即元素對應相乘。
#     vdot            兩個向量的點積
#     inner            兩個數組的內積
#     matmul        兩個數組的矩陣積
#     determinant    數組的行列式
#     solve            求解線性矩陣方程
#     inv            計算矩陣的乘法逆矩陣

# Numpy廣播的規則可理解成:結構相同,點對點;結果不同,分別匹配。[]是最小單元,按最小單元匹配。
# Numpy中邏輯盡量用邏輯操作運算符&/|,少用關鍵字and/or
# Numpy的向量化操作比純Python速度更快。

 


免責聲明!

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



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