二维数组的 Numpy 删除

时间:2021-01-25 16:42:12

标签: python arrays python-3.x numpy

我有一个形状为 (10, 3) 的 ndarray 和一个长度为 10 的索引列表:

import numpy as np
arr = np.arange(10* 3).reshape((10, 3))
idxs = np.array([0, 1, 1, 1, 2, 0, 2, 2, 1 , 0])

我想使用 numpy delete(或更适合该任务的 numpy 函数)删除 arr 中的值,如每行的 idxs 所示。因此,在 arr 的第 0 行中,我想删除第 0 个条目,在第一个条目中删除第一个条目,在第二个条目中删除第一个条目,依此类推。

我尝试过类似的东西

np.delete(arr, idxs, axis=1)

但它不会工作。然后我尝试构建一个这样的索引列表:

idlist = [np.arange(len(idxs)), idxs]
np.delete(arr, idlist)

但这也没有给我想要的结果。

2 个答案:

答案 0 :(得分:2)

让我们尝试通过遮罩提取其他项目,然后重塑:

arr[np.arange(arr.shape[1]) != idxs[:,None]].reshape(len(arr),-1)

答案 1 :(得分:2)

@Quang 的回答很好,但可能会从一些解释中受益。


np.delete 适用于整行或整列,而不是从每个行或列中选择的元素。

In [30]: arr = np.arange(10* 3).reshape((10, 3))
    ...: idxs = np.array([0, 1, 1, 1, 2, 0, 2, 2, 1 , 0])

从数组中选择项目很容易:

In [31]: arr[np.arange(10), idxs]
Out[31]: array([ 0,  4,  7, 10, 14, 15, 20, 23, 25, 27])

选择除这些之外的所有内容,需要做更多的工作。 np.delete 是复杂的通用代码,根据删除规范执行不同的操作。但它可以做的一件事是创建一个 True 掩码,并将删除项设置为 False

对于您的 2d 案例,我们可以:

In [33]: mask = np.ones(arr.shape, bool)
In [34]: mask[np.arange(10), idxs] = False
In [35]: arr[mask]
Out[35]: 
array([ 1,  2,  3,  5,  6,  8,  9, 11, 12, 13, 16, 17, 18, 19, 21, 22, 24,
       26, 28, 29])

boolean 索引会产生一个平面数组,所以我们需要重塑以获得二维:

In [36]: arr[mask].reshape(10,2)
Out[36]: 
array([[ 1,  2],
       [ 3,  5],
       [ 6,  8],
       [ 9, 11],
       [12, 13],
       [16, 17],
       [18, 19],
       [21, 22],
       [24, 26],
       [28, 29]])

Quand 的回答以另一种方式创建了掩码:

In [37]: arr[np.arange(arr.shape[1]) != idxs[:,None]]
Out[37]: 
array([ 1,  2,  3,  5,  6,  8,  9, 11, 12, 13, 16, 17, 18, 19, 21, 22, 24,
       26, 28, 29])