how to modify a 2D numpy array at specific locations without a loop?

Each Answer to this Q is separated by one/two green lines.

I have a 2D numpy array and I have a arrays of rows and columns which should be set to a particular value. Lets consider the following example

 a = array([[1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]])

I want to modify entries at rows [0,2] and columns [1,2]. This should result in the following array

 a = array([[1, 2, 0],
           [4, 5, 0],
           [7, 8, 9]])

I did following and it resulted in modifying each sequence of column in every row

rows = [0,1]
cols = [2,2]
b=a[numpy.ix_(rows,columns)]

It resulted in the following array modifying every column of the specified array

array([[1, 0, 0],
       [4, 5, 6],
       [7, 0, 0]])

Some one could please let me know how to do it?

Thanks a lot

EDIT: It is to be noted that rows and columns coincidently happend to be sequentia. The actual point is that these could be arbitrary and in any order. if it is rows = [a,b,c] and cols=[n x z] then I want to modify exactly three elements at locations (a,n),(b,x),(c,z).

Adding to what others have said, you can modify these elements using fancy indexing as follows:

In [39]: rows = [0,1]

In [40]: cols = [2,2]

In [41]: a = np.arange(1,10).reshape((3,3))

In [42]: a[rows,cols] = 0

In [43]: a
Out[43]: 
array([[1, 2, 0],
       [4, 5, 0],
       [7, 8, 9]])

You might want to read the documentation on indexing multidimensional arrays:
http://docs.scipy.org/doc/numpy/user/basics.indexing.html#indexing-multi-dimensional-arrays

The key point is:

if the index arrays have a matching shape, and there is an index array
for each dimension of the array being indexed, the resultant array has
the same shape as the index arrays, and the values correspond to the
index set for each position in the index arrays.

Importantly this also allows you to do things like:

In [60]: a[rows,cols] = np.array([33,77])

In [61]: a
Out[61]: 
array([[ 1,  2, 33],
       [ 4,  5, 77],
       [ 7,  8,  9]])

where you can set each element independently using another array, list or tuple of the same size.

one work around: ndarray.flatten, np.put(), ndarray.reshape

try ndarray.flatten(array), that way you are dealing with a one dim array which can be manipulated with numpy.put(array,[indices],[values]). Then use ndarray.reshape() to get to the original dimensions.

First off, your description of the “correct” array doesn’t match the columns and rows you specify…

To get your “correct” array, you’d do this:

a[:2, 2] = 0

To modify the second and third columns of the first and third rows, (rows [0,2] and columns [1,2]) you’d do what you’re doing… (Your description of modifying rows [0,2] and columns [1,2] is exactly the result you get, right?)

It should be as simple as a[0,2]=0 and a[1,2]=0. You could also do a[0:2,2]=0. The ‘:’ based range indexing in python is a half-open interval [0,2) which actually range from 0 to 1 (the end point of 2 is not included).


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .