Python 在numpy数组中选择行

Python 在numpy数组中选择行,python,arrays,numpy,Python,Arrays,Numpy,我有一个形状(n,4)的numpy数组(mat)。该数组有四列和大量(n)行。前三列表示我计算中的x,y,z列。我希望选择numpy数组中x列的值低于给定数字(min\u x)或高于给定数字(max\u x)的行,以及y列的值低于给定数字(min\u y)或高于给定数字(max\u y)的行其中,z列的值低于给定数字(min_z)或高于给定数字(max_z) 这就是我目前尝试实现此期望功能的方式: import numpy as np mark = np.where( ( (mat[:,0]&

我有一个形状
(n,4)
的numpy数组(
mat
)。该数组有四列和大量(
n
)行。前三列表示我计算中的
x
y
z
列。我希望选择numpy数组中
x
列的值低于给定数字(
min\u x
)或高于给定数字(
max\u x
)的行,以及
y
列的值低于给定数字(
min\u y
)或高于给定数字(
max\u 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]]
将numpy导入为np
标记=np,其中((材料[:,0]max_x))和\
((mat[:,1]max_y))和\
((mat[:,2]max_z)))
mat_new=mat[:,标记[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)

不幸的是,您无法控制精确的边界条件(
我只需删除
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]
x,y,z,u=mat.T
掩码=((x最大值x))&
((y最大值)&
((z max_z)))
mat_new=mat[遮罩]

您现在拥有的看起来不错。但是,由于您正在询问实现所需功能的其他方法:您可以为每个行索引创建一个一维布尔掩码,该掩码为
True
False
。下面是一个示例

>>> 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])
这种方法的一点不同之处在于它是可伸缩的:不必单独指定每个坐标条件,您可以在两个数组中指定它们,一个用于上限阈值,一个用于下限阈值,然后利用NumPy的矢量化和广播来构建遮罩


np.all()
说,测试所有值是否为
True
,行方式。它捕获问题中的“和”条件,而
|
操作符捕获“或”。

谢谢Brad,答案看起来很棒(编辑前我对输出有点困惑,但编辑后答案更有意义。)我应该能够使用
是的,如果你想少用或同样好用广播,那也行。我希望你被选中。你在样本上试过吗?你得到了不满意的结果吗?@MadPhysicast:我在样本上试过。它给出了预期的(完美的)结果。=)然后我会说这是一个很好的方法:)虽然被接受的答案有点聪明。
>>> 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]])