python不改變二維數組相對位置,得到對應行(列)滿足條件的新數組
有時候,程序中會用到不改變二維數組相對位置,得到元素滿足對應條件的行。
比如,給定一個座標數組,要求剔除掉x,y座標不滿足>0條件的座標。
引子:一維數組
對於一維數組來說,實現這個功能很簡單。有多種方法可以選擇。
方法一:直接法
A = np.array([1,2,3,4,5,6,0,-2,7,8,9])
result = A[A>0]
# 輸出:array([1,2,3,4,5,6,7,8,9])。可以看到已經刪掉了小於0的元素
print(result)
方法二:where()+數組切片
通過np.where()函數獲取滿足條件的元素所在的位置,然後利用數組切片找出。
A = np.array([1,2,3,4,5,6,0,-2,7,8,9])
ind = np.where(A>0)
result = A[ind]
# 輸出:array([1,2,3,4,5,6,7,8,9])。可以看到已經刪掉了小於0的元素
print(result)
二維數組
對於二維數組來說,使用上邊兩個方法都會導致數組展開成一維的,如下。
#首先生成一個2行6列的隨機整數組
A= np.random.randint(-4,4,(2,6))
print("A:",A)#每次運行生成的數組不一樣
#方法一:
ind = np.where(A>0)
result1 = A[ind]
print("result1:",result1)
#方法二:
result2 = A[A>0]
print("result2:",result2)
#方法三:同方法二,只是使用了array.nonzero()函數尋找非0索引
ind = A.nonzero()
result3 = A[ind]
print("result3:",result3)
運行結果:
A:
[[ 1 -3 0 1 3 2]
[ 0 1 1 -3 0 2]]
result1:
array([1, 1, 3, 2, 1, 1, 2])
result2:
array([1, 1, 3, 2, 1, 1, 2])
result3:
array([1, 1, 3, 2, 1, 1, 2])
可以看到,以上三種方法都改變了數組本來的結構。展成了一維數組。
要想維持數組本來的結構,就需要用到 all()
和 any()
函數。
他們的實現原理是:對數組中的每個元素判斷的邏輯值再按行(列)進行一個邏輯合併。
可選參數:axis
- axis =0 列。
- axis = 1行。
兩兩組合之下,可以靈活地實現四種功能。比如,對於一個二維數組A來說:
A= np.array([[1,-3,0,1,3,2],[0,1,1,-3,0,2]])
print("A:",A)
ind1 = (A>0).all(0)#找出所有元素都大於零的列索引
res1 = A[:,ind1] #得到A元素中每個元素均大於0的列
print("res1:",res1)
ind2 = (A>0).any(0)#找出任一元素大於零的列索引
res2 = A[:,ind2]#得到A元素中任一元素大於0的列
print("res2:",res2)
ind3 = (A>0).all(1)#找出所有元素都大於零的行索引
res3 = A[ind3,:]#得到A元素中所有元素都大於0的行
print("res3:",res3)
ind4 = (A>0).any(1)#找出任一元素大於零的行索引
res4 = A[ind4,:]#得到A元素中任一元素大於0的行
print("res4:",res4)
返回結果如下:
A: [[ 1 -3 0 1 3 2]
[ 0 1 1 -3 0 2]]
res1:
[[2]
[2]]
res2:
[[ 1 -3 0 1 3 2]
[ 0 1 1 -3 0 2]]
res3: []
res4:
[[ 1 -3 0 1 3 2]
[ 0 1 1 -3 0 2]]
最後,補充一下MATLAB實現類似功能的語句:B = A(:,all(A > 0,1))
,兩者很相似,但是從語法簡潔性來看,還是MATLAB更簡潔一點。革命尚未成功,python仍需努力啊!