更改不在索引列表中的 NumPy 数组的值
Posted
技术标签:
【中文标题】更改不在索引列表中的 NumPy 数组的值【英文标题】:Change the values of a NumPy array that are NOT in a list of indices 【发布时间】:2013-06-01 05:02:52 【问题描述】:我有一个像这样的 NumPy 数组:
a = np.arange(30)
我知道我可以使用例如花哨的索引替换位于位置 indices=[2,3,4]
的值:
a[indices] = 999
但是如何替换不在indices
中的位置的值呢?会像下面这样吗?
a[ not in indices ] = 888
【问题讨论】:
【参考方案1】:显然,集合没有通用的not
运算符。您的选择是:
-
从一组通用索引中减去您的
indices
集(取决于 a
的形状),但这会有点难以实现和阅读。
某种迭代(for
-loop 可能是您最好的选择,因为您肯定希望使用索引已排序这一事实)。
创建一个填充新值的新数组,并选择性地从旧数组复制索引。
b = np.repeat(888, a.shape)
b[indices] = a[indices]
【讨论】:
【参考方案2】:我不知道有一种干净的方式来做这样的事情:
mask = np.ones(a.shape,dtype=bool) #np.ones_like(a,dtype=bool)
mask[indices] = False
a[~mask] = 999
a[mask] = 888
当然,如果您更喜欢使用 numpy 数据类型,您可以使用dtype=np.bool_
-- 输出不会有任何差异。这只是一个偏好问题。
【讨论】:
为什么不使用np.ones_like
在旁注中,您可以将最后几行替换为对numpy.where
的一次调用(这是它真正有用的主要情况)。例如。 a = np.where(mask, 888, 999)
.
@JoeKington -- 是的,这对这种情况会更好。 (但它确实分配了一个新数组)——我只是想证明可以使用 ~
运算符来否定掩码变量。
@mgilson - 好点!这是很多人不知道的事情,你的例子很好地说明了这一点。
@JoeKington -- 我想a[...] = np.where(mask,888,999)
可能会在适当的位置覆盖a
,这展示了很少人知道的省略号运算符:)【参考方案3】:
仅适用于一维数组:
a = np.arange(30)
indices = [2, 3, 4]
ia = np.indices(a.shape)
not_indices = np.setxor1d(ia, indices)
a[not_indices] = 888
【讨论】:
【参考方案4】:刚刚克服了类似的情况,这样解决了:
a = np.arange(30)
indices=[2,3,4]
a[indices] = 999
not_in_indices = [x for x in range(len(a)) if x not in indices]
a[not_in_indices] = 888
【讨论】:
这是低效的(这对于有几十万条目的数据集很重要)。以上是关于更改不在索引列表中的 NumPy 数组的值的主要内容,如果未能解决你的问题,请参考以下文章