7

I have a NxM numpy array filled with zeros and a 1D numpy array of size N with random integers between 0 to M-1. As you can see the dimension of the array matches the number of rows in the matrix. Each element in the integer array means that at that given position in its corresponding row must be set to 1. For example:

# The matrix to be modified
a = np.zeros((2,10))
# Indices array of size N
indices = np.array([1,4])
# Indexing, the result must be
a = a[at indices per row]
print a

[[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]]

I tried using the indexing a[:,indices] but this sets the same indices for each row, and this finally sets all the rows with ones. How can I set the given index to 1 per row?

SurvivalMachine
  • 7,946
  • 15
  • 57
  • 87
Alejandro Sazo
  • 796
  • 15
  • 31

2 Answers2

13

Use np.arange(N) in order to address the rows and indices for columns:

>>> a[np.arange(2),indices] = 1
>>> a
array([[ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.]])

Or:

>>> a[np.where(indices)+(indices,)] = 1
>>> a
array([[ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.]])
Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • 1
    Fantastic. That means that I must learn the difference between accesing a row by simple slicing like 0:2, or just : for all rows) and give the indices to access row and columns as pairs to set the value. – Alejandro Sazo Sep 10 '16 at 22:27
  • @AlejandroSazo Yes, indeed, also not that you can pass the column and rows indices as a tuple to array. So for example `a[np.where(indices)+(indices,)] = 1` will do the same job too. – Mazdak Sep 10 '16 at 22:31
  • Can someone explain why using `np.arange(nrows)` works, but using the colon `:` doesnt work. @Kasramvd I thought the colon is equivalent to "use all rows", and `np.arange(nrows)` defaults to `np.array([0,1,2,...,nrows-1])` which is the same thing as using all rows. Is it because you need to explicitly state every row index because numpy zips the row,column if you provide it, but performs no zip if you use the colon? That's my hunch – Corey Levinson Feb 18 '20 at 23:13
  • What happens with the second option when indices are 0? I reckon that would rise an error. – myradio Mar 18 '20 at 08:03
2

You should also check the np.eye() function which does exactly what you want. It basically creates 2D arrays filled with zero and diagonal ones.

>>> np.eye(a.shape[1])[indices]
array([[0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.]])
Ersel Er
  • 731
  • 6
  • 22