You could easily write an extension to ndarray that maps axis names to
indices and vice versa.

Joe

On Tue, May 17, 2022, 21:32 Paul Korir <polaris...@gmail.com> wrote:

> Thanks for your replies.
>
> In retrospect, I realise that using the shape will not be helpful for a
> cubic array i.e. the permutations of (10, 10, 10) are all (10, 10, 10)!
> However, the problem remains. Let me try to explain.
>
> Short version
> The problem boils down to the meaning of axis indices as arguments to
> swapaxes and transpose (and any related functions). Swapping axes or
> transposing an array gives new meanings to the indices. For example,
> suppose I have a volume of shape C, R, S. Then 0 will refer to C, 1 will
> refer to R and 2 will refer to S. After I transpose it, say using (1, 2, 0)
> so that the shape becomes R, S, C then now 0 will refer to R, 1 will refer
> to S and 2 will refer to C. I can no longer reverse the transposition or
> transpose it predictably to achieve a certain shape, which is an important
> operation in some applications where the meaning of the axes is significant.
>
> Long version
> Suppose I have a volume of shape (C, R, S) and I have a corresponding
> assignment of physical axes so that C=X, R=Y and S=Z. This is equivalent to
> placing the volume with C along the X axis, R along Y axis and S along the
> Z axis. Now, suppose I would like to permute the axes by only making
> reference to the axis names: what is the shape corresponding to the
> orientation (Z, Y, X)?
>
> This is a simple example because we only swap two axes and the resulting
> shape is the same as performing the same swap in the shape: (S, R, C). If
> we knew the indices of the axis names then we can infer these and pass them
> to swapaxes or transpose:
>
> vol = numpy.random.rand(C, R, S) # of shape (C, R, S) -> (X, Y, Z)
> # now (Z, Y, X)
> new_vol = numpy.swapaxes(vol, 0, 2)
> new_vol.shape # (S, R, C)
>
> The same applies to a double swap e.g. (Y, Z, X), though it is less
> straightforward using swapaxes. swapaxes only takes two indices (obviously)
> so we would need to call it twice reflecting the two swaps required. So we
> have to somehow figure which axes to swap successively: ((0, 2) then (0,
> 1)). We can do this in one step with numpy.transpose simply using indices
> (1, 2, 0).
>
> However, (and this is the big 'however'), how would we reverse this? The
> array has no memory of the original axes and 0, 1, and 2 now refer to the
> current axes. This is where the axes names (e.g. X, Y and Z) would come in
> handy.
>
> Axis names will allow permutations to happen predictably since the array
> will 'remember' what the original references were.
>
> Here is what I propose: an API to numpy.ndarray with some identity e.g.
>
> vol = numpy.random.rand(C, R, S)
> vol.shape # C, R, S
> vol.axes = ('X', 'Y', 'Z') # C=X, R=Y, S=Z
> new_vol = vol.permute_axes(('Z', 'Y', 'X'))
> # either
> new_vol.axes # ('X', 'Y', 'Z') # preserve orientation but change shape
> new_vol.shape # S, R, C
> # or
> new_vol.axes # ('Z', 'Y', 'X') # preserve shape but change orientation
> new_vol.shape # C, R, S
> # we can now reverse the permutation
> old_vol = new_vol.permute_axes(('X', 'Y', 'Z'))
> numpy.array_equal(vol, old_vol) # True
>
> I've checked the numpy API documentation and there is no attribute .axes
> present so this is the best candidate. Additionally, this will require the
> .permute_axes(<axes_names>) method/function.
>
> Thanks for your consideration.
>
> Paul
> _______________________________________________
> NumPy-Discussion mailing list -- numpy-discussion@python.org
> To unsubscribe send an email to numpy-discussion-le...@python.org
> https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
> Member address: jfoxrabinov...@gmail.com
>
_______________________________________________
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com

Reply via email to