[SciPy-User] Reshaping Question

Anne Archibald peridot.faceted@gmail....
Wed Nov 4 21:49:57 CST 2009


2009/11/4 David Warde-Farley <dwf@cs.toronto.edu>:
>
> On 4-Nov-09, at 9:05 PM, Anne Archibald wrote:
>
>> Reshape sometimes creates copies. It tries hard not to, and if you
>> assign the shape attribute rather than calling reshape it won't ever
>> make a copy, but if necessary reshape will copy the input array:
>>
>> In [42]: np.transpose(c.reshape(2,2,2,2),
>> (0,2,1,3)).reshape(4,4)Out[42]:
>> array([[ 0,  1,  4,  5],
>>       [ 2,  3,  6,  7],
>>       [ 8,  9, 12, 13],
>>       [10, 11, 14, 15]])
>>
>> The trick is to use transpose to do an arbitrary permutation of the
>> input axes, and also to rearrange the first axis with an additional
>> reshape.
>
> D'oh. When he said reshape I was thinking purely in terms of what
> could be done with .reshape(). I didn't even think about .transpose().
>
> Is it then the .transpose() call that triggers the copy in this
> situation?

No, transpose() never needs to copy. It's the reshape.

In [3]: a = np.arange(6)

In [4]: a.shape = (2,3)

Here a's shape can be changed without copying the data, so the assignment works.

In [5]: b = a.T

In [6]: b.reshape(6)
Out[6]: array([0, 3, 1, 4, 2, 5])

Here b has been reshaped using the method, which returns a new array
that has copied the underlying data.

In [7]: b.shape = 6,
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/home/peridot/<ipython console> in <module>()

AttributeError: incompatible shape for a non-contiguous array

This didn't work because assignment to the shape attribute is not
allowed to copy the data, and there's no way for this reshape to work
without copying the data.

The error message is misleading, because there are a number of
copy-less rearrangements that are possible even with non-contiguous
arrays:

In [9]: c = np.arange(12)[::2]

In [10]: c.shape = (2,3)

In [11]: c.shape = (3,2)

IIRC there are still a few rearrangements that can in principle be
done without copying the data that numpy doesn't recognize, but it's
fairly good at avoiding copies. This is not necessarily a good thing,
since it can mean that users expect reshape() never to copy data and
then become surprised when they fail to get a view when handed some
array whose strides are especially peculiar. So I think the best rule
is, if you want a view, always assign to the shape attribute.

Anne


More information about the SciPy-User mailing list