[Numpy-discussion] bug in reshape ?

Friedrich Romstedt friedrichromstedt@gmail....
Tue Nov 22 19:57:28 CST 2011


2011/11/23  <josef.pktd@gmail.com>:
> might be an old story >>> np.__version__  -> '1.5.1'

I have only a numpy 1.4.1 for testing atm, but I believe this corner
case never occured and hence never got fixed since then.  Confirming
your issue on that.

> It thought for once it's easier to use reshape to add a new axis
> instead of ...,None
> but my results got weird (normal(0,1) sample of 2.13795875e-314)

What do you mean by "sample of 2.13....e-314"?

>>>> x = 1
>>>> y = np.arange(3)
>>>> z = np.arange(2)[:,None]
>>>> np.broadcast(x,y,z)
> <numpy.broadcast object at 0x04C0DCA0>
>>>> np.broadcast_arrays(x,y,z)
> [array([[1, 1, 1],
>       [1, 1, 1]]), array([[0, 1, 2],
>       [0, 1, 2]]), array([[0, 0, 0],
>       [1, 1, 1]])]
>>>> x1, y1, z1 = np.broadcast_arrays(x,y,z)
>>>> map(np.shape, (x1, y1, z1))
> [(2, 3), (2, 3), (2, 3)]
>
> shape looks fine, let's add an extra axis with reshape
>
>>>> x1.reshape(2,3,1)
> array([[[          1],
>        [          1],
>        [ 1099464714]],
>
>       [[-2147481592],
>        [        184],
>        [          1]]])
>
> what's that ?

I think it has to do with this:

>>> x1.strides
(0, 0)

Let's have a look at
http://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html#numpy.reshape.
 From there we have this nice examples:

"
>>> a = np.array([[1,2,3], [4,5,6]])
>>> np.reshape(a, 6)
array([1, 2, 3, 4, 5, 6])
>>> np.reshape(a, 6, order='F')
array([1, 4, 2, 5, 3, 6])
"

So my guess would be that numpy.reshape either assumes C or F order, I
don't know what the "preserve" 'A' flag has to be interpreted as?

At least this would explain the behaviour.

>>>> (0+x1).reshape(2,3,1)
> array([[[1],
>        [1],
>        [1]],
>
>       [[1],
>        [1],
>        [1]]])
>
>>>> (y1*1.).reshape(2,3,1)
> array([[[ 0.],
>        [ 1.],
>        [ 2.]],
>
>       [[ 0.],
>        [ 1.],
>        [ 2.]]])
>
>>>> (y1).reshape(2,3,1)
> array([[[          0],
>        [          1],
>        [          2]],
>
>       [[          0],
>        [ 1099447643],
>        [-2147483648]]])

Guess the zero in the second block of (y1) is just coincidentally.

>>>> x1, y1, z1 = np.broadcast_arrays(x,y,z)
>>>> x1[...,None]
> array([[[1],
>        [1],
>        [1]],
>
>       [[1],
>        [1],
>        [1]]])
>
>>>> x1.shape
> (2, 3)
>>>> x1.reshape(2,3,1)
> array([[[          1],
>        [          1],
>        [ 1099464730]],
>
>       [[-2147479536],
>        [ -445054780],
>        [ 1063686842]]])
>
>
> the background story: playing broadcasting tricks for
> http://projects.scipy.org/scipy/ticket/1544

Have not looked at that.

> Josef

Some more:

>>> x1.reshape((2, 3, 1), order='A')
array([[[      1],
        [2506242],
        [6755216]],

       [[ 262144],
        [7272256],
        [7278624]]])
>>> x1.reshape((2, 3, 1), order='C')
array([[[      1],
        [2506242],
        [6755216]],

       [[ 262144],
        [7272256],
        [7278624]]])
>>> x1.reshape((2, 3, 1), order='F')
array([[[      1],
        [6755216],
        [7272256]],

       [[2506242],
        [ 262144],
        [7278624]]])

So I guess it's not a bug, it's a feature ;-)

Reshape is low-level plumbing apparently.  It should be, since the
strides involved not necessarily are compatible with each other, you
can reshape (11, 7) to (7, 11).

Maybe a warning if the strides contain zeros might be appropriate to
avoid reading in arbitrary memory, though.

Friedrich


More information about the NumPy-Discussion mailing list