代码之家  ›  专栏  ›  技术社区  ›  James L.

如何在numpy数组中设置单个索引

  •  2
  • James L.  · 技术社区  · 6 年前

    我正在尝试使用数组在其他数组中设置值。不幸的是,它没有设置一个值,而是以某种方式覆盖了一组值。发生了什么,我怎样才能实现我想要的?

    >>> target = np.array( [ [0,1],[1,2],[2,3] ])
    >>> target
    array([[0, 1],
           [1, 2],
           [2, 3]])
    >>> actions = np.array([0,0,0])
    >>> target[actions] #The first row, 3 times
    array([[0, 1],
           [0, 1],
           [0, 1]])
    >>> target[:,actions] #The first column, 3 times
    array([[0, 0, 0],
           [1, 1, 1],
           [2, 2, 2]])
    >>> values = np.array([7,8,9])
    >>> target[:,actions] = values #why isnt this working?
    >>> target
    array([[9, 1],
           [9, 2],
           [9, 3]])
    #Actually want
    #array([[7, 1],
    #       [8, 2],
    #       [9, 3]])
    
    >>> target = np.array( [ [0,1],[1,2],[2,3] ]) #reset to original value
    >>> actions = np.array([0,1,0])
    >>> target[:,actions] = values.reshape(3, 1)
    array([[7, 7],
           [8, 8],
           [9, 9]])
    #Actually want
    #array([[7, 1],
    #       [1, 8],
    #       [9, 3]])
    
    3 回复  |  直到 6 年前
        1
  •  1
  •   user2357112    6 年前

    target[:,actions] 选择的同一列 target 三次。

    当你说 target[:,actions] = values ,您要做的是:

    1. 将7赋给列中的所有值三次。
    2. 将8赋给列中的所有值,三次。
    3. 将9赋给列中的所有值三次。

    因此,在列中的所有值中都有9个。

    如果您坚持这种笨拙的三重数据写入,您可以通过转换写入来修复它:

    target[:,actions] = values.reshape(3, 1)
    

    这会写 [7,8,9] 到柱子上,三次。显然这是浪费,你可以这样做:

    target[:,actions[-1]] = values
    

    效果应该相同,这样可以节省计算。

        2
  •  1
  •   hpaulj    6 年前

    将[7,8,9]写入第一列的两种方法:

    基本索引(带切片):

    In [396]: target[:,0] = [7,8,9]           # all rows, 1st column
    In [397]: target
    Out[397]: 
    array([[7, 1],
           [8, 2],
           [9, 3]])
    

    高级索引(有2个列表)

    In [398]: target[[0,1,2],[0,0,0]] = [7,8,9]   # pair [0,0],[1,0],[2,0]
    In [399]: target
    Out[399]: 
    array([[7, 1],
           [8, 2],
           [9, 3]])
    

    第二种方法也适用于混合柱:

    In [400]: target = np.array( [ [0,1],[1,2],[2,3] ])
    In [401]: target[[0,1,2],[0,1,0]] = [7,8,9]
    In [402]: target
    Out[402]: 
    array([[7, 1],
           [1, 8],
           [9, 3]])
    

    广播开始发挥作用。在这样的情况下,有3个可能的数组可以广播-2维和源数组。

    这样的高级索引生成一个一维数组。因此源数组必须匹配:

    In [403]: target[[0,1,2],[0,1,0]]
    Out[403]: array([7, 8, 9])
    

    (1,3)可以广播到(3,1),但(3,1)不能:

    In [404]: target[[0,1,2],[0,1,0]] = np.array([[7,8,9]])
    In [405]: target[[0,1,2],[0,1,0]] = np.array([[7,8,9]]).T
    ...
    ValueError: shape mismatch: value array of shape (3,1) could not be broadcast to indexing result of shape (3,)
    

    这种索引是不寻常的。注意结果是(3,3)。

    In [412]: target[:,[0,0,0]]
    Out[412]: 
    array([[0, 0, 0],
           [1, 1, 1],
           [2, 2, 2]])
    

    A(3,1)来源:

    In [413]: np.array([[7,8,9]]).T
    Out[413]: 
    array([[7],
           [8],
           [9]])
    In [414]: target[:,[0,0,0]] = _
    In [415]: target
    Out[415]: 
    array([[7, 1],
           [8, 2],
           [9, 3]])
    

    (3,1)可以广播到(3,3)。它可以工作,但最终分配[7,8,9]3次,全部分配给同一个0列。


    另一种分配第一列的方法:

    In [423]: target[np.ix_([0,1,2],[0,0,0])]
    Out[423]: 
    array([[0, 0, 0],
           [1, 1, 1],
           [2, 2, 2]])
    

    再次A(3,3),接受A(3,1):

    In [424]: target[np.ix_([0,1,2],[0,0,0])] = np.array([[7,8,9]]).T
    In [425]: target
    Out[425]: 
    array([[7, 1],
           [8, 2],
           [9, 3]])
    

    ix_ 生成两个可以相互广播的数组,在本例中是列向量和行向量:

    In [426]: np.ix_([0,1,2],[0,0,0])
    Out[426]: 
    (array([[0],
            [1],
            [2]]), array([[0, 0, 0]]))
    

    我可以选择的所有元素 target 使用:

    In [430]: target[np.ix_([0,1,2],[0,1])]
    Out[430]: 
    array([[0, 1],
           [1, 2],
           [2, 3]])
    

    杂乱无章:

    In [431]: target[np.ix_([2,0,1],[1,0])]
    Out[431]: 
    array([[3, 2],
           [1, 0],
           [2, 1]])
    
        3
  •  -1
  •   James L.    6 年前

    我不能用 : 但是,下面的索引是通过使用索引数组来实现的。不知道为什么 以下内容: 方法不起作用,如果有人能想出解决方法,我会接受它。

    >>> target = np.array( [ [0,1],[1,2],[2,3] ])
    >>> rows = np.arange(target.shape[0])
    >>> actions = np.array([0,1,0])
    >>> values = np.array([7,8,9])
    >>> target[rows,actions] = values
    >>> target
    array([[7, 1],
           [1, 8],
           [9, 3]])