簡體   English   中英

選擇numpy數組中的行

[英]Selecting rows in numpy array

我有一個形狀(n,4)的numpy數組( mat (n,4) 該數組有四列和大量( n )行。 前三列代表我計算中的xyz列。 我希望選擇那些numpy數組的行,其中x列的值低於給定的數字( min_x )或高於給定數字的值( max_x ),並且y列的值低於給定的數字( min_y )或上面的值給定數字( max_y )和z列的值低於給定數字( min_z )或高於給定數字( max_z )的值。

這就是我目前試圖實現這個所需功能的方式:

import numpy as np

mark = np.where( ( (mat[:,0]<=min_x) | \
            (mat[:,0]>max_x) ) & \
                 ( (mat[:,1]<=min_y) | \
            (mat[:,1]>max_y) ) & \
                 ( (mat[:,2]<=min_z) | \
            (mat[:,2]>max_z) ) )

mat_new = mat[:,mark[0]]

我正在使用的技術是否正確,以及實現所需功能的最佳方法? 我將非常感謝任何幫助。 謝謝。

對我來說看上去很好。 您可以通過將列與中間值進行比較來使其更緊湊:

mark = (np.abs(mat[:,0] - (max_x + min_x) / 2) > (max_x - min_x) / 2) &
       (np.abs(mat[:,1] - (max_y + min_y) / 2) > (max_y - min_y) / 2) &
       (np.abs(mat[:,2] - (max_z + min_z) / 2) > (max_z - min_z) / 2)

不幸的是,您無法再控制精確的邊界條件( < vs <= )。 此外,這可能是最慢的解決方案,甚至比原始解決方案更慢。

你現在擁有什么看起來很好。 但是,由於您正在詢問實現所需功能的其他方法:您可以為每個行索引創建一個1維布爾掩碼,該掩碼為TrueFalse 這是一個例子。

>>> import numpy as np
>>> np.random.seed(444)

>>> shape = 15, 4
>>> mat = np.random.randint(low=0, high=10, size=shape)
>>> mat
array([[3, 0, 7, 8],
       [3, 4, 7, 6],
       [8, 9, 2, 2],
       [2, 0, 3, 8],
       [0, 6, 6, 0],
       [3, 0, 6, 7],
       [9, 3, 8, 7],
       [3, 2, 6, 9],
       [2, 9, 8, 9],
       [3, 2, 2, 8],
       [1, 5, 6, 7],
       [6, 0, 0, 0],
       [0, 4, 8, 1],
       [9, 8, 5, 8],
       [9, 4, 6, 6]])

# The thresholds for x, y, z, respectively
>>> lower = np.array([5, 5, 4])
>>> upper = np.array([6, 6, 7])
>>> idx = len(lower)
# Parentheses are required here.  NumPy boolean ops use | and &
# which have different operator precedence than `or` and `and`
>>> mask = np.all((mat[:, :idx] < lower) | (mat[:, :idx] > upper), axis=1)

>>> mask
array([False, False,  True,  True, False, False,  True, False,  True,
        True, False, False,  True, False, False])

現在通過mask索引mat會將其約束為maskTrue行索引:

>>> mat[mask]
array([[8, 9, 2, 2],
       [2, 0, 3, 8],
       [9, 3, 8, 7],
       [2, 9, 8, 9],
       [3, 2, 2, 8],
       [0, 4, 8, 1]])

這種方法有點不同的是它是可擴展的:你可以在兩個數組中指定它們,一個用於上限,一個用於下限,然后利用NumPy的矢量化和廣播,而不是單獨指定每個坐標條件。建立面具。

np.all()說, 測試所有值都是True ,行方式。 它從你的問題中捕獲“和”條件,而| 操作員捕獲“或”。

我只是刪除np.where並使用布爾掩碼代替

x,y,z,_ = mat.T
mask = ( ( (x <= min_x) | (x > max_x) ) &
         ( (y <= min_y) | (y > max_y) ) &
         ( (z <= min_z) | (z > max_z) ) ) 
mat_new = mat[mask]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM