【问题标题】:Numpy: Insert value into different column for each rowNumpy:将值插入每行的不同列
【发布时间】:2017-10-02 15:55:36
【问题描述】:

我正在尝试插入一个 numpy 矩阵,给定一个掩码,该掩码定义每行一个单元格。实际上,它在每一行中插入一个值,但具有不同的列。我尝试使用np.insert() 没有成功:

>>> x
array([[False, False,  True, False, False],
       [False, False,  True, False, False],
       [False, False,  True, False, False],
       [False, False,  True, False, False],
       [False, False,  True, False, False]], dtype=bool)
>>> y = np.arange(25).reshape(5,5)
>>> y
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
>>> np.insert(y, np.where(x)[1], 99, axis=1)
array([[ 0,  1, 99, 99, 99, 99, 99,  2,  3,  4],
       [ 5,  6, 99, 99, 99, 99, 99,  7,  8,  9],
       [10, 11, 99, 99, 99, 99, 99, 12, 13, 14],
       [15, 16, 99, 99, 99, 99, 99, 17, 18, 19],
       [20, 21, 99, 99, 99, 99, 99, 22, 23, 24]])

每当我尝试根据 x 掩码插入时,它最终都会重复值。

如上所述,掩码可能会以一种不是简单列的方式设置。例如:

>>> x = np.zeros((5, 5), dtype=bool)
>>> x[1:, 2] = True
>>> x[0, 1] = True
>>> x
array([[False,  True, False, False, False],
       [False, False,  True, False, False],
       [False, False,  True, False, False],
       [False, False,  True, False, False],
       [False, False,  True, False, False]], dtype=bool)

这意味着我不能简单地将特定列指定为要插入的索引:

>>> np.insert(y, 2, [99, 99, 99, 99, 99], axis=1)
array([[ 0,  1, 99,  2,  3,  4],
       [ 5,  6, 99,  7,  8,  9],
       [10, 11, 99, 12, 13, 14],
       [15, 16, 99, 17, 18, 19],
       [20, 21, 99, 22, 23, 24]])

期望的输出是:

array([[ 0,  99, 1,  2,  3,  4],
       [ 5,  6, 99,  7,  8,  9],
       [10, 11, 99, 12, 13, 14],
       [15, 16, 99, 17, 18, 19],
       [20, 21, 99, 22, 23, 24]])

任何帮助将不胜感激!

【问题讨论】:

  • 那么,掩码每行只有一个 True 值?
  • 正确。每行只有一个 True 值。困难的部分是它可以与其他 True 值位于不同的列中。

标签: python numpy matrix


【解决方案1】:

方法#1:这是boolean-indexing的一种方法-

def insert_one_per_row(arr, mask, putval):
    mask_ext = np.column_stack((mask, np.zeros((len(mask),1),dtype=bool)))
    out = np.empty(mask_ext.shape, dtype=arr.dtype)
    out[~mask_ext] = arr.ravel()
    out[mask_ext] = putval
    return out

示例运行 -

In [88]: y
Out[88]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [89]: x
Out[89]: 
array([[False,  True, False, False, False],
       [False, False,  True, False, False],
       [False, False, False, False,  True],
       [ True, False, False, False, False],
       [False, False,  True, False, False]], dtype=bool)

In [90]: insert_one_per_row(y, x, putval=99)
Out[90]: 
array([[ 0, 99,  1,  2,  3,  4],
       [ 5,  6, 99,  7,  8,  9],
       [10, 11, 12, 13, 99, 14],
       [99, 15, 16, 17, 18, 19],
       [20, 21, 99, 22, 23, 24]])

我们还可以为每行分配不同的值 -

In [91]: insert_one_per_row(y, x, putval=[-1,-2,-3,-4,-5])
Out[91]: 
array([[ 0, -1,  1,  2,  3,  4],
       [ 5,  6, -2,  7,  8,  9],
       [10, 11, 12, 13, -3, 14],
       [-4, 15, 16, 17, 18, 19],
       [20, 21, -5, 22, 23, 24]])

方法#2:我们将在掩码上获得扁平化的True 位置,并在这些位置的输入数组的扁平化版本上插入带有np.insert 的新值,就像这样 -

def insert_one_per_row_v2(arr, mask, putval):
    idx = np.flatnonzero(mask)
    return np.insert(arr.ravel(), idx, putval).reshape(arr.shape[0],-1)

【讨论】:

    【解决方案2】:

    其实你可以用np.where

    np.where(x, np.full_like(y, 99), y)
    

    这是输出:

    In [9]: x
    Out[9]: 
    array([[False,  True, False, False, False],
           [False, False,  True, False, False],
           [False, False,  True, False, False],
           [False, False,  True, False, False],
           [False, False,  True, False, False]], dtype=bool)
    
    In [10]: y
    Out[10]: 
    array([[ 0,  1,  2,  3,  4],
           [ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14],
           [15, 16, 17, 18, 19],
           [20, 21, 22, 23, 24]])
    
    In [11]: np.where(x, np.full_like(y, 99), y)
    Out[11]: 
    array([[ 0, 99,  2,  3,  4],
           [ 5,  6, 99,  8,  9],
           [10, 11, 99, 13, 14],
           [15, 16, 99, 18, 19],
           [20, 21, 99, 23, 24]])
    

    谢谢

    【讨论】:

    • 看起来这实际上覆盖了这些索引处的值。这主要是我正在寻找的,但我不想覆盖。我想用那个索引来插入。
    • 然后试试@Divakar 的回答
    猜你喜欢
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    相关资源
    最近更新 更多