索引和遍歷
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)>