13

Say I have an array

np.zeros((4,2))

I have a list of values [4,3,2,1], which I want to assign to the following positions: [(0,0),(1,1),(2,1),(3,0)]

How can I do that without using the for loop or flattening the array?

I can use fancy index to retrieve the value, but not to assign them.

======Update=========

Thanks to @hpaulj, I realize the bug in my original code is.

When I use zeros_like to initiate the array, it defaults to int and truncates values. Therefore, it looks like I did not assign anything!

4
  • 1
    arr[idx[:,0], idx[:,1]] = [4,3,2,1], where idx = np.array([[0,0],[1,1],[2,2],[3,1]])? Commented Jan 27, 2017 at 18:36
  • 2
    Position (2,2) is out of bounds of the original array. Commented Jan 27, 2017 at 18:37
  • Yes, you can, use fancy indexing for assignment. Try a[[0,1,2,3], [0,1,2,1]] = 4,3,2,1. Commented Jan 27, 2017 at 18:38
  • @wim Yes, you are right. I changed the question. Commented Jan 27, 2017 at 18:57

2 Answers 2

35

You can use tuple indexing:

>>> import numpy as np
>>> a = np.zeros((4,2))
>>> vals = [4,3,2,1]
>>> pos = [(0,0),(1,1),(2,0),(3,1)]
>>> rows, cols = zip(*pos)
>>> a[rows, cols] = vals
>>> a
array([[ 4.,  0.],
       [ 0.,  3.],
       [ 2.,  0.],
       [ 0.,  1.]])
Sign up to request clarification or add additional context in comments.

5 Comments

Yes, it works. However, it is really strange that if I initialize the a as np.zeros_like, it does not assign values!
Edit follow up: It works in a toy sample but not in my previous code. I am not sure where the bug is.
Pay attention to dtypes when using zeros_like. Assigning floats to int slots truncates the values.
Doesn't seem to work in 3d. Not sure if it's a bug or that I need adapt the indexing to fit 3d
what if i had an example where i want some of these to occur multiple times. so 4 appearing in 0,0 and 1,0?
4

Here is a streamlined version of @wim's answer based on @hpaulj's comment. np.transpose automatically converts the Python list of tuples into a NumPy array and transposes it. tuple casts the index coordinates to tuples which works because a[rows, cols] is equivalent to a[(rows, cols)] in NumPy.

import numpy as np
a = np.zeros((4, 2))
vals = range(4)
indices = [(0, 0), (1, 1), (2, 0), (3, 1)]
a[tuple(np.transpose(indices))] = vals
print(a)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.