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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.