numpy-索引和遍歷


索引和遍歷

NumPy 的切片創建了 view 而不是像內置的python序列(如string、tuple和list)那樣的副本。在從大型數組中提取一小部分時必須小心,因為提取的小部分包含對大型原始數組的引用,在對其派生的所有數組進行垃圾收集之前,不會釋放這些數組的內存。在這種情況下, copy() 建議使用。

  • 當切片的數量少於數組維度時,缺失的維度索引被認為是一個完整切片, 省略與使用“:”或“…”等價

基礎索引

一維數組

一維數組的索引和 Python 中 list 結構索引十分相似,需要注意在切片索引的時候末尾的下標是取不到

a = np.array([0, 1, 2, 3, 4, 5])
print(type(a))
print(a[0])  # 0
print(a[2:4])  # [2 3]
print(a[1:3])  # [1 2]
print(a[1:5:2])  # [1 3]

二維數組

切片和索引
a = np.arange(12).reshape(3, 4)
print(a[2][0])  #8 
print(a[2,0])   #8
#第一種方式通過遞歸訪問,首先a[2]將得到array([8, 9, 10, 11]),然后a[2][0]訪問索引為0的數字,得到8;如果對數組的大小理解清楚了,那么第二種方式就是非常直接的指定了該數據在第0軸的索引2位置和第1軸的索引0位置。

a = np.array([[1,2,3,4,5],[6,7,8,9,10]])
print(a[0:1]) #截取第一行,返回 [[1 2 3 4 5]]
print(a[1,2:5]) #截取第二行,第三、四、五列,返回 [8 9 10]
print(a[1,:]) #截取第二行,返回 [ 6  7  8  9 10]

不同行,采用 ,  隔開
同一行滿足列表索引規則
arr_2d = np.arange(16).reshape(4,4)
print(arr_2d)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]]

print(arr_2d[0, 1:3])
print(arr_2d[0:2, 1:3])

# [1 2]
# [[1 2]
#  [5 6]]

print(arr_2d[:, 1:3])
#[[ 1  2]
# [ 5  6]
# [ 9 10]
# [13 14]]
a = np.array([[1,2,3],[3,4,5],[4,5,6]])   

# 第2列元素
print(a[...,1])   

# 第2行元素 
print(a[1,...])

# 第2列及剩下的所有元素
print(a[...,1:])

#[2 4 5]
#[3 4 5]
#[[2 3] 
# [4 5] 
# [5 6]]

高級索引

使用索引數組進行索引

a = np.arange(5,16)

print(a[[0, 1]])  # [5 6]
print(a[np.array([[0, 1]])])   # [[5 6]]
print(a[np.array([[0, 1], [2, 3]])])  # [[5 6] [7 8]]

#---------------------------------------------------------------
#取值矩陣的四個角
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])   

print(x) 
rows = np.array([[0,0],[3,3]]) 
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]  
print(y)


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

#[[ 0  2]
# [ 9 11]]


使用布爾值數組進行索引

#獲取大於 5 的元素
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])   
print(x)
# 現在我們會打印出大於 5 的元素
print(x[x>5])
#[[ 0  1  2]
# [ 3  4  5]
# [ 6  7  8]
# [ 9 10 11]]

#[ 6  7  8  9 10 11]

#---------------------------------------------------------------
zarten = np.random.randn(5,4)
print(zarten)
print('')

zarten_bool = np.array([True, False, False, False, True])
print(zarten[zarten_bool])

#[[0.12370779 0.60020841]
# [0.19022537 0.65618376]
# [0.5231678  0.18813379]
# [0.53643122 0.26875578]
# [0.55525969 0.23672487]]

#[[0.12370779 0.60020841]
# [0.55525969 0.23672487]]

zarten_1 = np.array(['A', 'B', 'C', 'D', 'A'])
print(zarten[zarten_1 == 'A'])     # != 不等於,& 與運算,| 或運算
#[[0.12370779 0.60020841]
# [0.55525969 0.23672487]]
#---------------------------------------------------------------
#~(取反運算符)來過濾 NaN
a = np.array([np.nan,  1,2,np.nan,3,4,5])
print(a[~np.isnan(a)])

#---------------------------------------------------------------
a = np.array(['www', 'finthon', 'com'])
b = np.arange(12).reshape(3, 4)
print(b[a == 'finthon'])
#[[4 5 6 7]]

花式索引

是利用整數數組進行行索引的方式

a = np.arange(12).reshape(3, 4)
print(a)
b = a[[2, 0, 1]]  # 一維整數數組, 針對的是 0 維度
print(b)
#[[ 0  1  2  3]
# [ 4  5  6  7]
# [ 8  9 10 11]]

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

c=a[[1, 1, 2, 2], [1, 3, 0, 2]] # 二維整數數組,針對的是兩個維度
print(c) 
# [ 5  7  8 10]

np.ix_()函數

np.ix_()函數,能把兩個一維數組 轉換為 一個用於選取方形區域的索引器

a = np.arange(10).reshape(2, 5)
b=a[[0,1],[2,4]]                    #整數數組索引
c=a[np.ix_([0, 1], [2, 4])]         #np.ix_() 整數數組索引
print(b)
print(c)

#[2 9]
#[[2 4]
# [7 9]]

d=a[[True, True], [2, 4]]
e=a[np.ix_([True, True], [2, 4])]
print(d)
print(e)

#[2 9]
#[[2 4]
# [7 9]]

np.where()

np.where(condition, [x, y])必寫參數是condition(判斷條件),后邊的x和y是可選參數

  • 當where內只有一個參數時,那個參數表示條件,當條件成立時,where返回的是每個符合condition條件元素的坐標,返回的是以元組的形式

  • 當where內有三個參數時,第一個參數表示條件,當條件成立時where方法返回x,當條件不成立時where返回y

其實你不應該在這個目錄分區里

a = np.array([2, 4, 6, 8, 10])
print(a)
print(np.where(a > 5))
print(a[np.where(a > 5)])
#[ 2  4  6  8 10]
#(array([2, 3, 4], dtype=int64),)
#[ 6  8 10]

#---------------------------------------------------------------
x= np.random.randint(0,4,size=(3,3))
print(x)

print(np.where(x>2))

#[[0 2 1]
# [0 1 3]
# [3 1 0]]
#(array([1, 2], dtype=int64), array([2, 0], dtype=int64))

print(np.where(x==2))
(array([0], dtype=int64), array([1], dtype=int64))

#---------------------------------------------------------------
a = np.arange(10)
print(a)
aa = np.where(a, 1, -1)
print(aa)
aaa = np.where(a > 5, 5, -5)
print(aaa)

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

Numpy數組遍歷

按照內存布局打印數組元素

numpy.nditer 迭代器返回的元素順序,是和數組內存布局一致的,這樣做是為了提升訪問的效率,默認是行序優先

arr = np.arange(6).reshape(2,3)
for i in np.nditer(arr):
    print(i, end=" ")
    
#0 1 2 3 4 5

#---------------------------------------------------------------
#默認的打印順序是行序優先   order="C"
for i in np.nditer(arr.T):
    print(i, end=" ")
#0 1 2 3 4 5

#控制遍歷順序

print ('以 F 風格順序排序:')
for i in np.nditer(arr, order="F"):
    print(i, end=" ")

# 可選參數 op_flags  默認 迭代遍歷的數組為只讀對象(read-only)

arr1 = np.arange(8).reshape(2,4)
for i in np.nditer(arr1, op_flags=["readwrite"]):
    i[...] = i**2
    
#[[ 0  1  4  9]
# [16 25 36 49]]
# flags 參數可以接受傳入一個數組或元組,它可以接受下列值
    
參數 描述
c_index 可以跟蹤 C 順序的索引
f_index 可以跟蹤 Fortran 順序的索引
multi-index 每次迭代可以跟蹤多重索引類型
external_loop 給出的值是具有多個值的一維數組,而不是零維數組
#設置 flags=["c_index"],可以實現類似 list 的 enumerate 函數的效果
cit =  np.nditer(arr, flags=["c_index"])
while not cit.finished:
    print("value:", cit[0], "index:<{}>".format(cit.index))
    cit.iternext()
# value: 0 index:<0>
# value: 1 index:<1>
# value: 2 index:<2>
# value: 3 index:<3>
# value: 4 index:<4>
# value: 5 index:<5>
# value: 6 index:<6>
# value: 7 index:<7>   
 
#---------------------------------------------------------------
mul_it = np.nditer(arr, flags=['multi_index'])

while not mul_it.finished:
    print("value:", mul_it[0], "index:<{}>".format(mul_it.multi_index))
    mul_it.iternext()

# value: 0 index:<(0, 0)>
# value: 1 index:<(0, 1)>
# value: 2 index:<(0, 2)>
# value: 3 index:<(0, 3)>
# value: 4 index:<(1, 0)>
# value: 5 index:<(1, 1)>
# value: 6 index:<(1, 2)>
# value: 7 index:<(1, 3)>


免責聲明!

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



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