4

I would like to convert numpy array into numpy array of arrays.

I have an array: a = [[0,0,0],[0,255,0],[0,255,255],[255,255,255]]

and I would like to have: b = [[[0,0,0],[0,0,0],[0,0,0]],[[0,0,0],[255,255,255],[0,0,0]],[[0,0,0],[255,255,255],[255,255,255]],[[255,255,255],[255,255,255],[255,255,255]]]

Is there any easy way to do it?

I have tried with np.where(a == 0, [0,0,0],[255,255,255]) but I got the following error:

ValueError: operands could not be broadcast together with shapes
2
  • what is the rule to replace the values? Commented Dec 16, 2019 at 16:26
  • If you are simply replicating, this is relevant : stackoverflow.com/questions/32171917. Commented Dec 16, 2019 at 17:27

3 Answers 3

4

You can use broadcast_to as

b = np.broadcast_to(a, (3,4,3))

where a was shape (3,4). Then you need to swap the axes around

import numpy as np
a = np.array([[0,0,0],[0,255,0],[0,255,255],[255,255,255]])
b = np.broadcast_to(a, (3,4,3))
c = np.moveaxis(b, [0,1,2], [2,0,1])
c

giving

array([[[  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0]],

       [[  0,   0,   0],
        [255, 255, 255],
        [  0,   0,   0]],

       [[  0,   0,   0],
        [255, 255, 255],
        [255, 255, 255]],

       [[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]]])

A more direct method broadcasting method suggested by @Divakar is

 b = np.broadcast(a[:,:,None], (4,3,3))

which produces the same output without axis swapping.

Sign up to request clarification or add additional context in comments.

1 Comment

Good idea there. Shorter and faster with extending dims upfront and then broadcasting : np.broadcast_to(a[:,:,None], (4,3,3)).
2

What you tried will work with the following small modification:

a = np.array(a)
np.where(a[...,None]==0,[0,0,0],[255,255,255])

To make multidimensional indexing available we have to cast a to array first. a[...,None] adds a new dimension at the end of a to accomodate the triplets 0,0,0 and 255,255,255.

1 Comment

@makis I've added a bit of explanation.
1
In [204]: a = np.array([[0,0,0],[0,255,0],[0,255,255],[255,255,255]])           
In [205]: a.shape                                                               
Out[205]: (4, 3)

Looks like you want to replicate each element 3 times, making a new trailing dimension. We can do that using repeat (after adding the new trailing dimension):

In [207]: a.reshape(4,3,1).repeat(3,2)                                          
Out[207]: 
array([[[  0,   0,   0],
        [  0,   0,   0],
        [  0,   0,   0]],

       [[  0,   0,   0],
        [255, 255, 255],
        [  0,   0,   0]],

       [[  0,   0,   0],
        [255, 255, 255],
        [255, 255, 255]],

       [[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]]])
In [208]: _.shape                                                               
Out[208]: (4, 3, 3)

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.