更改不在索引列表中的 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 数组的值的主要内容,如果未能解决你的问题,请参考以下文章

Numpy:如何在 numpy 中选择项目并为其赋值

使用重复索引递增 Numpy 数组

如何使用 numpy 或 pandas 创建(或更改)数组/列表的维度?

numpy数组符号化与函数向量化

用元组列表索引一个 numpy 数组

numpy数组列表中N个最高元素的索引[重复]