如果 2d-numpy 数组中包含特定元素,则删除它们

Remove rows in a 2d-numpy array if they contain a specific element

我有一个 2d-np.array 矩阵,我想删除特定列中包含元素 x 的所有行。我的目标是 return 一个没有这些行的矩阵,所以它应该更小。 我的函数如下所示:

def delete_rows(matrix, x, col):
    for i in range(matrix.shape[0]-1):
        if(matrix[i,col] == x):
            np.delete(matrix, i, axis = 0)
    return matrix

遗憾的是,在我的测试中,删除行后矩阵的形状保持不变。我认为删除的行已被带 0 的行替换。 关于如何实现我的目标有什么建议吗?

这可以简单地在一行中完成:

import numpy as np

def delete_rows(matrix, x, col):
    return matrix[matrix[:,col]!=x,:]

例如,如果我们要从矩阵 A 中删除第二列中包含 5 的所有行:

>>> A = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> print(delete_rows(A, 5, 1))
[[1 2 3]
 [7 8 9]]

假设你有这样一个数组:

array([[12,  5,  0,  3, 11,  3,  7,  9,  3,  5],
       [ 2,  4,  7,  6,  8,  8, 12, 10,  1,  6],
       [ 7,  7, 14,  8,  1,  5,  9, 13,  8,  9],
       [ 4,  3,  0,  3,  5, 14,  0,  2,  3,  8],
       [ 1,  3, 13,  3,  3, 14,  7,  0,  1,  9],
       [ 9,  0, 10,  4,  7,  3, 14, 11,  2,  7],
       [12,  2,  0,  0,  4,  5,  5,  6,  8,  4],
       [ 1,  4,  9, 10, 10,  8,  1,  1,  7,  9],
       [ 9,  3,  6,  7, 11, 14,  2, 11,  0, 14],
       [ 3,  5, 12,  9, 10,  4, 11,  4,  6,  4]])

您可以像这样删除所有包含 3 的行:

row_mask = np.apply_along_axis(np.any, 1, arr == 3)
arr = arr[~row_mask]

你的新数组看起来像这样


array([[ 2,  4,  7,  6,  8,  8, 12, 10,  1,  6],
       [ 7,  7, 14,  8,  1,  5,  9, 13,  8,  9],
       [12,  2,  0,  0,  4,  5,  5,  6,  8,  4],
       [ 1,  4,  9, 10, 10,  8,  1,  1,  7,  9]])

编辑: 为要检查的特定列添加了条件

您不需要为此使用任何应用方法。它可以用基本的布尔索引来解决,如下 -

arr[~(arr[:,col] == val),:]
  1. arr[:,col] 从数组中选择特定列
  2. arr[:,col] == val 检查值和 returns True 它存在的地方,否则 False
  3. ~(arr[:,col] == val) 反转 TrueFalse
  4. arr[~(arr[:,col] == val),:] 仅保留布尔索引为 True 的行并丢弃所有 False

示例解决方案

arr = np.array([[12, 10, 12,  0,  9,  4, 12, 11],
                [ 3, 10, 14,  5,  4,  3,  6,  6],
                [12, 10,  1,  0,  5,  7,  5, 10],
                [12,  8, 14, 14, 12,  3, 14, 10],
                [ 9, 14,  3,  8,  1, 10,  9,  6],
                [10,  3, 11,  3, 12, 13, 11, 10],
                [ 0,  6,  8,  8,  5,  5,  1, 10], #<- this to remove
                [13,  6,  1, 10,  7, 10, 10, 13],
                [ 3,  3,  8, 10, 13,  0,  0, 10], #<- this to remove
                [ 6,  2, 13,  5,  8,  2,  8, 10]])
#                         ^
#                 this column to check


#boolean indexing approach
val, col = 8,2 #value to check is 8 and column to check is 2

out = arr[~(arr[:,col] == val),:] #<-----
out
array([[12, 10, 12,  0,  9,  4, 12, 11],
       [ 3, 10, 14,  5,  4,  3,  6,  6],
       [12, 10,  1,  0,  5,  7,  5, 10],
       [12,  8, 14, 14, 12,  3, 14, 10],
       [ 9, 14,  3,  8,  1, 10,  9,  6],
       [10,  3, 11,  3, 12, 13, 11, 10],
       [13,  6,  1, 10,  7, 10, 10, 13],
       [ 6,  2, 13,  5,  8,  2,  8, 10]])

如果你想检查所有列中的值,那么试试这个 -

arr[~(arr == val).any(1),:]

如果您只想保留包含该值的行,只需从条件中删除 ~

arr[(arr[:,col] == val),:]

如果您也想删除该列,请使用 np.delete -

np.delete(arr[~(arr[:,col] == val),], col, axis=1)

Note: You cannot remove both rows and columns at once using np.delete so if you plan to use it, you will need to do np.delete two times once for axis = 0 (rows) and once for axis = 1 (columns)