1
$\begingroup$

I cannot find anything in the documentation but it was used in some starter code for a class I am taking at school. Upon testing per below, it seems to reverse the order of the dimensions of an numpy array.

pic = np.ones((3,4,5))
print(pic.shape,"\n", pic)
#new_shape is the reverse of pic.shape
new_shape = pic.shape[::-1]
print(new_shape)

This outputs:

(3, 4, 5) 
 [[[1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]]

 [[1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]]

 [[1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]
  [1. 1. 1. 1. 1.]]]
(5, 4, 3)

In the starter code it was used in this way:

res_img = cv2.resize(img, sub_img.shape[::-1])

There are some other tricks that are planted in the starter code (to show us that they are there I'm guessing). Here is another example:

channels = blue, green, red = np.moveaxis(color_img, 2, 0) #move channels to pos 0

The np.moveaxis() moved channels to the first dim position but it's assigned to blue, green and red at the same time via Python multiple assignment? When I looked up multiple assignment, I only saw stuff like var1, var2 = 1, 2. Also np.moveaxis() returns an array with the new shape so I have to stretch my imagination to assume the first axis can be assigned to variables. Is this correct?

My instructor just replied that np.split() does the splitting but the documentation does not say anything about this being implicitly called when np.moveaxis() is called.

Does anyone know what is really happening?

$\endgroup$
  • $\begingroup$ I think this question probably belongs on stack overflow, rather than here. $\endgroup$ – Paul Aug 25 '19 at 11:56
  • $\begingroup$ @Paul, you're probably right. I posted it here because it was in the context of manipulating numpy image arrays that are either inputs or outputs to CNNs. $\endgroup$ – mLstudent33 Aug 25 '19 at 15:41
1
$\begingroup$

Note that when you do:

pic.shape[::-1]

You only reverse the elements of the shape are of pic. So pic.shape is (3,4,5] and reversed, it's (5, 4, 3).

What happens with the multiple assignment is just that you can assign the elements along the first index to individual variables. For example:

pic = np.array( [['x1','x2','x3'],['y1','y2','y3']]) 

The first index can be 0 or 1, the second index can be 0, 1 or 2. I can assign the x-vector to a and the y-vector to be like this:

a, b = pic

In [18]: a
Out[18]: array(['x1', 'x2', 'x3'], dtype='<U2')
In [19]: b
Out[19]: array(['y1', 'y2', 'y3'], dtype='<U2')

The call to moveaxis reformats the image, by moving axis 0 to position 2 in the array of axes. My pic doesn't have a position 2 (since it only has 2 dimensions), but I can swap axis 0 with axis 1:

In [11]: np.moveaxis(pic, 1, 0)
Out[11]: 
array([['x1', 'y1'],
   ['x2', 'y2'],
   ['x3', 'y3']], dtype='<U2')

And now I can assign (x1, y1) to a, (x2, y2) to b and (x3, y3) to c:

a, b, c = np.moveaxis(pic, 1, 0)

In [14]: a
Out[14]: array(['x1', 'y1'], dtype='<U2')

There is no call to split anywhere here. I think what confused you is just the multiple assignment from a numpy array, which allows the direct assignment of columns to individual variables. In combination with moveaxis this would allow you to split the red, green and blue images in a single command.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ great answer but still scratching my head as to why nothing is mentioned in the documentation. $\endgroup$ – mLstudent33 Aug 25 '19 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.