首先让我们探索一下简单移除的替代方案(没有这个起始位置问题的变化):
首先创建一个具有唯一且易于识别的值的x:
In [787]: x = list(range(10))
In [788]: x
Out[788]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
一种列表理解方法 - 可能不是最快的,但相当清晰且无错误:
In [789]: [v for i,v in enumerate(x) if i not in x_remove]
Out[789]: [0, 2, 3, 6, 7, 8, 9]
您的np.delete 方法:
In [790]: np.delete(x, x_remove)
Out[790]: array([0, 2, 3, 6, 7, 8, 9])
将x 转换为数组有一个缺点,这不是一项简单的任务(时间方面)。它还创建了一个新数组。我的猜测是它更慢。
尝试就地移除:
In [791]: y=x[:]
In [792]: for i in x_remove:
...: del y[i]
...:
In [793]: y
Out[793]: [0, 2, 3, 4, 6, 8, 9]
哎呀——错了。我们需要从头开始(最大的索引)。这是一个众所周知的 Python '配方':
In [794]: y=x[:]
In [795]: for i in x_remove[::-1]:
...: del y[i]
...:
...:
In [796]: y
Out[796]: [0, 2, 3, 6, 7, 8, 9]
在幕后np.delete 采取蒙面方法:
In [797]: arr = np.array(x)
In [798]: arr
Out[798]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [799]: mask = np.ones(arr.shape, bool)
In [800]: mask[x_remove] = False
In [801]: mask
Out[801]:
array([ True, False, True, True, False, False, True, True, True,
True])
In [802]: arr[mask]
Out[802]: array([0, 2, 3, 6, 7, 8, 9])
现在来解决将x_remove 应用于x 的切片的问题。 x的切片没有切片参数的记录。也就是说,您无法轻易确定 y = x[2:] 缺少两个值。 (嗯,我可以通过比较x 和y 的一些属性来推断它,但不能仅从y 来推断)。
所以无论你如何删除,你都必须先调整x_remove的值。
In [803]: x2 = np.array(x_remove)-2
In [804]: x2
Out[804]: array([-1, 2, 3])
In [805]: [v for i,v in enumerate(x[2:]) if i not in x2]
Out[805]: [2, 3, 6, 7, 8, 9]
这没问题,但-1 可能是个问题。我们不希望它意味着the last element。所以我们必须首先过滤掉负面指标才能安全。
In [806]: np.delete(x[2:], x2)
/usr/local/bin/ipython3:1: FutureWarning: in the future negative indices will not be ignored by `numpy.delete`.
#!/usr/bin/python3
Out[806]: array([2, 3, 6, 7, 8, 9])
如果delete 没有忽略负数索引,它可能会得到这样的掩码 - 最后是False:
In [808]: mask = np.ones(arr[2:].shape, bool)
In [809]: mask[x2] = False
In [810]: mask
Out[810]: array([ True, True, False, False, True, True, True, False])