4

I want to associate values into an array by index, without iterating. Picture the following, but for hundreds of thousands of values:

to_populate = [
    [[0, 0], 1],
    [[1, 1], 100],
    [[2, 3], 29],
    [[3, 2], 33],
]

mat = np.empty((4, 4))
mat[:] = np.nan

for idx, val in to_populate:
    x, y = idx
    mat[x, y] = val

# array([[  1.,  nan,  nan,  nan],
#        [ nan, 100.,  nan,  nan],
#        [ nan,  nan,  nan,  29.],
#        [ nan,  nan,  33.,  nan]])

I'm thinking of it as conceptually like the reverse of np.argwhere, but with specific values rather than a predicate condition.

mat = np.random.randn(3, 3)

# array([[ 0.89298522,  0.41059024,  0.32770948],
#        [-0.91956498, -0.11774805, -1.42625182],
#        [ 1.28644586, -0.06951971, -0.88742959]])

np.argwhere(mat < 0)

# array([[1, 0],
#        [1, 1],
#        [1, 2],
#        [2, 1],
#        [2, 2]])

1 Answer 1

2

You can "unpack" to_populate into row indexes, column indexes and values and then use slicing:

import numpy as np
to_populate = [
    [[0, 0], 1],
    [[1, 1], 100],
    [[2, 3], 29],
    [[3, 2], 33],
]
# flatten the list
to_populate = np.array([[i[0][0], i[0][1], i[1]] for i in to_populate])

idx = to_populate[:,0]
idy = to_populate[:,1]
values = to_populate[:,2]

mat = np.full((4,4),np.nan)
mat[idx,idy]=values

mat
array([[  1.,  nan,  nan,  nan],
       [ nan, 100.,  nan,  nan],
       [ nan,  nan,  nan,  29.],
       [ nan,  nan,  33.,  nan]])
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! to_populate was being created from dataframe columns, so I can save a step and just index by the columns directly.

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.