【问题标题】:Change the values of a NumPy array that are NOT in a list of indices更改不在索引列表中的 NumPy 数组的值
【发布时间】:2013-06-01 05:02:52
【问题描述】:

我有一个像这样的 NumPy 数组:

a = np.arange(30)

我知道我可以使用例如花哨的索引替换位于位置 indices=[2,3,4] 的值:

a[indices] = 999

但是如何替换不在indices中的位置的值呢?会像下面这样吗?

a[ not in indices ] = 888

【问题讨论】:

    标签: python arrays numpy replace multidimensional-array


    【解决方案1】:

    显然,集合没有通用的not 运算符。您的选择是:

    1. 从一组通用索引中减去您的 indices 集(取决于 a 的形状),但这会有点难以实现和阅读。
    2. 某种迭代(for-loop 可能是您最好的选择,因为您肯定希望使用索引已排序这一事实)。
    3. 创建一个填充新值的新数组,并选择性地从旧数组复制索引。

      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
        

        【讨论】:

        • 这是低效的(这对于有几十万条目的数据集很重要)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-14
        • 2020-05-24
        • 2019-03-04
        • 2017-05-07
        • 2021-12-17
        • 2023-03-26
        相关资源
        最近更新 更多