BigBoy1337 BigBoy1337 - 6 months ago 16
Python Question

Unshape and reshape a numpy array?

I have an array of 56 images each with 2 channels for the pixels. Thus its shape is (1200, 800, 52, 2). I need to do a KNeighborsClassifier and it needs to be flattened so that all the pixels in all 52 images are in one column. So shape (1200*800*52,2). Then after the classification is performed - I need to know that I can unshape them in the correct order.

As a first step, I am trying to just unshape and reshape the same array and try to get it to be the same as the original.

Here is what I have tried which doesn't seem to work:

In [55]: Y.shape
Out[55]: (1200, 800, 2, 52)

In [56]: k = np.reshape(Y,(1200*800*52,2))

In [57]: k.shape
Out[57]: (49920000, 2)

In [58]: l = np.reshape(k,(1200,800,52,2))

In [59]: l.shape
Out[59]: (1200, 800, 52, 2)

In [60]: assert l == Y
/Users/alex/anaconda2/bin/ipython:1: DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.
#!/bin/bash /Users/alex/anaconda2/bin/python.app
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-60-9faf5e8e20ba> in <module>()


Edit: I made an error in k and Y's shapes. here is the corrected version, still with an error though

In [78]: Y.shape
Out[78]: (1200, 800, 2, 52)

In [79]: k = np.reshape(Y,(1200*800*52,2))

In [80]: k.shape
Out[80]: (49920000, 2)

In [81]: l = np.reshape(k,(1200,800,2,52))

In [82]: assert Y == l
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-82-6f6815930213> in <module>()
----> 1 assert Y == l

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Answer

(Y == l) is a boolean array of the same shape as Y and l.

assert expression evaluates expression in a boolean context. In other words, expression.__bool__() is called.

By design, the ndarray.__bool__ method raises

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

because it's not clear if __bool__ should return True when all the elements are True, or when any of the elements are True.

You can avoid the error by calling either the all or any method, depending on your intent. In your case you would want to assert that all values are equal:

assert (Y == l).all()

Since comparing floats for equality can sometimes return unexpected results due to the imprecision of floating point arithmetic, comparing floating point arrays for equality can also more safely be done with

assert np.allclose(Y, l)

Note that np.allclose accepts relative tolerance and absolute tolerance parameters to cope with floating-point imprecision.