From: A. M. A. <per...@gm...> - 2006-10-18 05:57:40
|
On 17/10/06, Travis Oliphant <oli...@ie...> wrote: > Charles R Harris wrote: > > > > In [3]: array([[1,2,3,4,5,6]]).reshape((3,2),order='F') > > Out[3]: > > array([[1, 4], > > [2, 5], > > [3, 6]]) > > > > I also don't understand why a copy is returned if 'F' just fiddles > > with the indices and strides; the underlying data should be the same, > > just the view changes. FWIW, I think both examples should be returning > > views. > > You are right, it doesn't need to. My check is not general enough. > > It can be challenging to come up with a general way to differentiate the > view-vs-copy situation and I struggled with it. In this case, it's the > fact that while self->nd > 1, the other dimensions are only of shape 1 > and so don't really matter. If you could come up with some kind of > striding check that would distinguish the two cases, I would appreciate it. I wrote, just for exercise I guess, a routine that checks to see if a copy is needed for a reshape (and if not, it computes the resulting strides) for an arbitrary array. (It currently only does a C-order reshape, but F-order would be an easy addition.) It does, however, successfully handle arbitrarily strided arrays with arbitrary arrangements of "1" dimensions having arbitrary strides. I think it also correctly handles 0 strides. I don't imagine you'd want to *use* it, but it does provide a complete solution to copy-less reshaping. I'd be happy to help with the C implementation built into numpy, but for the life of me I can't figure out how it works. A. M. Archibald P.S. I haven't written down a *proof* that this implementation never copies unnecessarily, but I'm pretty sure that it doesn't. It has a reshape_restricted that effectively does a ravel() first; this can't cope with things like length (5,2,3) -> length (5,3,2) unless the strides are conveniently equal, so there's a wrapper, reshape(), that breaks the reshape operation up into pieces that can be done by reshape_restricted. -AMA |