1

I have a (28,28) array a. And I want to obtain a (28,28,3) array b s.t. b[i][j][0] = b[i][j][1] = b[i][j][2] = a[i][j].

Is there any numpy shortcut to do this without tedious for loops?

xixumei
  • 111
  • 1
  • Just a side note: arrays support multidimensional indexing. Instead of `b[i][j][0]` you can and should use `b[i, j, 0]` which is more efficient. – Paul Panzer Dec 10 '17 at 05:14

3 Answers3

1
>>> import numpy as np
>>> a = np.zeros((28,28))
>>> b = np.dstack((a,a,a))
>>> a.shape
(28, 28)
>>> b.shape
(28, 28, 3)

Example:

>>> a = np.array([[1,2],[3,4]])
>>> b = np.dstack((a,a,a))
>>> a
array([[1, 2],
       [3, 4]])
>>> b
array([[[1, 1, 1],
        [2, 2, 2]],

       [[3, 3, 3],
        [4, 4, 4]]])
Kinght 金
  • 17,681
  • 4
  • 60
  • 74
1

You can append an axis to a and then repeat it n=3 times:

>>> a = np.random.randn(28, 28)
>>> b = np.repeat(np.atleast_3d(a), repeats=3, axis=-1)
>>> b.shape 
(28, 28, 3)

And as required,

>>> np.all(a == b[...,0])
True
>>> np.all(b[...,0] == b[...,1])
True
>>> np.all(b[...,1] == b[...,2])
True
tiao
  • 805
  • 1
  • 8
  • 20
0

You can allocate b and use broadcasting:

b = np.empty(a.shape + (3,), a.dtype)
b[...] = a[..., None]

If you only need read access, then a very efficient way is creating a strided view:

c = np.lib.stride_tricks.as_strided(a, a.shape + (3,), a.strides + (0,))

This shares its data with a meaning that when you write to c, a will also change. Moreover along the last axis the stride is zero meaning that for example c[1, 1, 0] and c[1, 1, 2] are the same memory, change one and the other will also change. If that's not desired make a copy:

b = c.copy()
Paul Panzer
  • 51,835
  • 3
  • 54
  • 99
  • You would need `writable = False` to actually make it *read only*. Without it, you still have *write access*. – Divakar Dec 10 '17 at 06:21
  • @Divakar just my way of saying don't write unless you know what you're doing. Btw. saw me winning an argument below the other answer using the `np.shares_memory` you showed me the other day? – Paul Panzer Dec 10 '17 at 06:32
  • Congratulations on the win? :) Well you know it's good to share info, the pun not intended ;) – Divakar Dec 10 '17 at 06:34