Can't reshape numpy array

30,840

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)
Share:
30,840
Nick Gilbert
Author by

Nick Gilbert

Updated on July 18, 2022

Comments

  • Nick Gilbert
    Nick Gilbert almost 2 years

    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?

  • abarnert
    abarnert over 10 years
    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.
  • askewchan
    askewchan over 10 years
    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.
  • abarnert
    abarnert over 10 years
    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.)