我有一个形状为(10,3)的数组和一个长度为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项,第1项删除第1项,第2项删除第1项,以此类推。
我试过像
np.delete(arr, idxs, axis=1)
,但它不会工作。然后我试着建立一个索引列表,像这样:
idlist = [np.arange(len(idxs)), idxs]
np.delete(arr, idlist)
但这也没有给我想要的结果。
@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
索引生成一个平面数组,因此我们需要重塑以获得2d:
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])
让我们尝试通过屏蔽来提取其他项,然后重塑:
arr[np.arange(arr.shape[1]) != idxs[:,None]].reshape(len(arr),-1)
感谢您的问题以及Quang和hpaulj的回答。我只想添加第二个场景,从另一个轴进行删除。
索引现在只有3个元素,因为arr
中只有3列,例如:
idxs2 = np.array([1,2,3])
要根据idxs2
中的索引删除每列的元素,可以这样做
arr.T[np.array(np.arange(arr.shape[0]) != idxs2[:,None])].reshape(len(idxs2),-1).T
,结果变成:
array([[ 0, 1, 2],
[ 6, 4, 5],
[ 9, 10, 8],
[12, 13, 14],
[15, 16, 17],
[18, 19, 20],
[21, 22, 23],
[24, 25, 26],
[27, 28, 29]])