pythonarraysnumpy

Numpy- strange behaviour of __setitem__ of array


Say we have an array:

a = np.array([
    [11, 12, 13],
    [21, 22, 23],
    [31, 32, 33],
    [41, 42, 43]
])

a[[1, 3], [0, 2]] = 0

So we want to set zeros to 0th and 2nd element at both 1st and 3rd rows. But what we get is:

[[11 12 13]
 [ 0 22 23]
 [31 32 33]
 [41 42  0]]

Why not:

[[11 12 13]
 [ 0 22 0]
 [31 32 33]
 [0 42  0]]

?


Solution

  • In

    import numpy as np
    a = np.array([
        [11, 12, 13],
        [21, 22, 23],
        [31, 32, 33],
        [41, 42, 43]
    ])
    a[[1, 3], [0, 2]] = 0
    a
    

    the last statement is equivalent to (edited)

    a[1, 0] = 0
    a[3, 2] = 0
    

    It gives the following:

    a = np.array([
        [11, 12, 13],
        [21, 22, 23],
        [31, 32, 33],
        [41, 42, 43]
    ])
    a[1, 0] = 0
    a[3, 2] = 0
    
    a
    # array([[11, 12, 13],
    #        [ 0, 22, 23],
    #        [31, 32, 33],
    #        [41, 42,  0]])
    

    In numpy's documentation, this is referenced as "advanced indexing"

    Advanced indexing is triggered when the selection object, obj, is a non-tuple sequence object, an ndarray (of data type integer or bool), or a tuple with at least one sequence object or ndarray (of data type integer or bool).

    In your case, your selection object is a tuple with at least one sequence object.