10

I have a function that is supposed to take a 1D array of integers and shapes it into a 2D array of 1x3 arrays. It then is supposed to take each 1x3 array and shift it into a 3x1 array. The result is supposed to be a 2D array of 3x1 arrays. Here is my function

def RGBtoLMS(rgbValues, rgbLength): #Method to convert from RGB to LMS
    print rgbValues
    lmsValues = rgbValues.reshape(-1, 3)
    print lmsValues
    for i in xrange(len(lmsValues)):
        lmsValues[i] = lmsValues[i].reshape(3, 1)

    return lmsValues

The issue rises when I try to change the 1x3 arrays to 3x1 arrays. I get the following output assuming rgbValues = [14, 25, 19, 24, 25, 28, 58, 87, 43]

[14 25 19 ..., 58 87 43]
[[14 25 19]
 [24, 25, 28]
 [58 87 43]]

ValueError [on line lmsValues[i] = lmsValues[i].reshape(3, 1)]: could not broadcast input array from shape (3,1) into shape (3)

How can I avoid this error?

Nick Gilbert
  • 4,159
  • 8
  • 43
  • 90
  • 1
    When you say 2D array of 1x3 arrays, is it of shape (n, n, 1, 3) ? An example here might help clarify! – Andy Hayden Nov 27 '13 at 21:20
  • 1
    The main issue is that each entry of `lmsValues` has a specified shape already, so assigning something to that with a different shape is not allowed. I agree with @AndyHayden , however, than a simple example of your input and expected output will be helpful in answering your question. – cm2 Nov 27 '13 at 21:26
  • Edited, now it should be more clear – Nick Gilbert Nov 27 '13 at 21:33
  • I think "2D array of 1x3 arrays" means "2D array with shape `(n, 3)`". @Nick, in numpy, an array is just a single object, whether 1d or 2d or nd. For lists, we say "list of lists" if it's '2d', but in numpy, that's just a '2d array'. Also, we still don't know what your desired output looks like. – askewchan Nov 27 '13 at 22:23

1 Answers1

8

As mentioned in the comments, you are really always just modifying one array with different shapes. It doesn't really make sense in numpy to say that you have a 2d array of 1 x 3 arrays. What that really is is actually a n x 3 array.

We start with a 1d array of length 3*n (I've added three numbers to your example to make the difference between a 3 x n and n x 3 array clear):

>>> import numpy as np

>>> rgbValues = np.array([14, 25, 19, 24, 25, 28, 58, 87, 43, 1, 2, 3])
>>> rgbValues.shape
(12,)

And reshape it to be n x 3:

>>> lmsValues = rgbValues.reshape(-1, 3)
>>> lmsValues
array([[14, 25, 19],
       [24, 25, 28],
       [58, 87, 43],
       [ 1,  2,  3]])
>>> lmsValues.shape
(4, 3)

If you want each element to be shaped 3 x 1, maybe you just want to transpose the array. This switches rows and columns, so the shape is 3 x n

>>> lmsValues.T
array([[14, 24, 58,  1],
       [25, 25, 87,  2],
       [19, 28, 43,  3]])

>>> lmsValues.T.shape
(3, 4)

>>> lmsValues.T[0]
array([14, 24, 58,  1])

>>> lmsValues.T[0].shape
(4,)

If you truly want each element in lmsValues to be a 1 x 3 array, you can do that, but then it has to be a 3d array with shape n x 1 x 3:

>>> lmsValues = rgbValues.reshape(-1, 1, 3)
>>> lmsValues
array([[[14, 25, 19]],

       [[24, 25, 28]],

       [[58, 87, 43]],

       [[ 1,  2,  3]]])

>>> lmsValues.shape
(4, 1, 3)

>>> lmsValues[0]
array([[14, 25, 19]])

>>> lmsValues[0].shape
(1, 3)
askewchan
  • 45,161
  • 17
  • 118
  • 134
  • 1
    Really, a 2D array of 1x3 arrays would be a 4D array. Or it could be a 2D array of `dtype=object` where each element is a 2D 1x3 array. Both of those are definitely doable. But neither one seems like anything the OP would actually want to do; I think this answer is what he actually _wants_, even if he doesn't know it. – abarnert Nov 27 '13 at 23:07
  • Haha, semantically, I think you're correct, @abarnert, but wouldn't that involve a size change? Or, I suppose it could be `(n, 1, 1, 3)`, lol. But yeah, my guess is the transpose is what he's after. – askewchan Nov 27 '13 at 23:18
  • Yes, without a resize, `(n, 1, 1, 3)`. Or `(1, n, 1, 3)`. Is it more unreasonable to lift each dimension once, or to list the same dimension twice in a row? It depends what you're trying to do, and I have no idea why he says he wants a 2D array of 1x3 arrays. (Especially since I don't think he actually wants that, he wants a 1D array of 1x3 arrays, exactly as you've given him.) – abarnert Nov 27 '13 at 23:42