Vegard J.
Vegard J.

Reputation: 307

numpy, mapping one array to parts of another

lets say i have one array

    a = numpy.arange(8*6*3).reshape((8, 6, 3))
    #and another:
    l = numpy.array([[0,0],[0,1],[1,1]]) #an array of indexes to array "a"
    #and yet another:
    b = numpy.array([[0,0,5],[0,1,0],[1,1,3]])

where "l" and "b" are of equal length, and i want to say

    a[l] = b

such that a[0][0] becomes [0,0,5], a[0][1] becomes [0,1,0] etc.

it seems to work fine when ive got one-dimensional arrays, but it gives me the error

    ValueError: array is not broadcastable to correct shape

when i try it with a 3-dimensional array.

Upvotes: 4

Views: 3223

Answers (2)

unutbu
unutbu

Reputation: 879321

import numpy as np

a = np.arange(8*6*3).reshape((8, 6, 3))
l = np.array([[0,0],[0,1],[1,1]]) #an array of indexes to array "a"
b = np.array([[0,0,5],[0,1,0],[1,1,3]])

a[tuple(l.T)] = b
print(a[0,0])
# [0 0 5]

print(a[0,1])
# [0 1 0]

print(a[1,1])
# [1 1 3]

Anne Archibald says,

When you are supplying arrays in all index slots, what you get back has the same shape as the arrays you put in; so if you supply one-dimensional lists, like

A[[1,2,3],[1,4,5],[7,6,2]]

what you get is

[A[1,1,7], A[2,4,6], A[3,5,2]]

When you compare that with your example, you see that

a[l] = b tells NumPy to set

a[0,0,1] = [0,0,5]
a[0,1,1] = [0,1,0]

and leaves the third element of b unassigned. This is why you get the error

ValueError: array is not broadcastable to correct shape

The solution is to transpose the array l into the correct shape:

In [50]: tuple(l.T)
Out[50]: (array([0, 0, 1]), array([0, 1, 1]))

(You could also use zip(*l), but tuple(l.T) is a bit quicker.)

Upvotes: 3

SteveWeber
SteveWeber

Reputation: 71

Or with your same arrays you can use

for i in range(len(l)):
    a[l[i][0]][l[i][1]]=b[i]

Upvotes: 0

Related Questions