[Numpy-discussion] .T Transpose shortcut for arrays again

Sasha ndarray at mac.com
Thu Jul 6 13:25:39 CDT 2006

On 7/6/06, Bill Baxter <wbaxter at gmail.com> wrote:
> On 7/7/06, Sasha <ndarray at mac.com> wrote:
> ... I think it's much
> more common to want to swap just two axes, and the last two seem a logical
> choice since a) in the default C-ordering they're the closest together in
> memory and b) they're the axes that are printed contiguously when you say
> "print A".

It all depends on how you want to interpret a rank-K tensor.  You seem
to advocate a view that it is a (K-2)-rank array of matrices and .T is
an element-wise transpose operation. Alternatively I can expect that
it is a matrix of (K-2)-rank arrays and then .T should be
swapaxes(0,1).  Do you have real-life applications of swapaxes(-2,-1)
for rank > 2?

> > and swapaxes(-2,-1) is
> > invalid for rank < 2.
> >
>  At least in numpy 0.9.8, it's not invalid, it just doesn't do anything.

That's bad.  What sense does it make to swap non-existing axes? Many
people would expect transpose of a vector to be a matrix.  This is the
case in S+ and R.

> > My main objection is that a.T is fairly cryptic
> > - is there any other language that uses attribute for transpose?
> Does it matter what other languages do?  It's not _that_ cryptic.

If something is clear and natural, chances are it was done before.
For me prior art is always a useful guide when making a design choice.
 For example, in R, the transpose operation is t(a) and works on rank
<= 2 only always returning rank-2.  K (an APL-like language) overloads
unary '+' to do swapaxes(0,1) for rank>=2 and nothing for lower rank.
Both R and K solutions are implementable in Python with R using 3
characters and K using 1(!) compared to your two-character ".T"
notation.  I would suggest that when inventing something new, you
should consider prior art and explain how you invention is better.
That's why what other languages do matter. (After all, isn't 'T'
chosen because "transpose" starts with "t" in the English language?)

>  The standard way to write transpose is with a little T superscript in the upper
> right.  We can't do that with ASCII so the T just appears after the dot.
> Makes perfect sense to me.  I'd vote for an operator if it were possible in
> python.  Something like A^T would be neat, maybe, or matlab's single-quote
> operator.

Well, you could overload __rpow__ for a singleton T and spell it A**T
... (I hope no one will take that proposal seriosely).   Visually, A.T
looks more like a subscript rather than superscript.

> > Adding .T to arrays will lead to less readable code because in
> > expressions like "a * b.T" it will not be clear whether * is a matrix
> > or elemenwise multiplication.
> That seems a pretty weak argument, since there are already lots of
> expressions you can write that don't make it clear whether some operation is
> a matrix operation or array operation.

This may be a weak argument for someone used to matrix notation, but
for me seeing a.T means: beware - tricky stuff here.

>  You could write a * b.transpose(1,0)
> right now and still not know whether it was matrix or element-wise
> multiplication.

Why would anyone do that if b was a matrix?

> > 2. .H :  This is an  O(n^2) complexity operation returning a copy so
> > it is not appropriate for an attribute.
> Not sure how you get O(n^2).   It just requires flipping the sign on the
> imaginary part of each element in the array.  So in my book that's O(n).
> But that does make it more expensive than O(1) transpose, yes.
In my book n is the size of the matrix as in "n x n matrix", but the
argument stays with O(n) as well.

> But probably a better solution
> would be to have matrix versions of these in the library as an optional
> module to import so people could, say, import them as M and use M.ones(2,2).

This is the solution used by ma, which is another argument for it.

> In short, I'm most enthusiastic about the .T attribute.  Then, given a .T,
> it makes sense to have a .H, both to be consistent with matrix, but also
> since it seems to be a big deal in other math packages like matlab.  Then
> given the current situation, I like the .M but I can imagine other ways to
> make .M less necessary.

I only raised a mild objection against .T, but the slippery slope
argument makes me dislike it much more.  At the very least I would
like to see a discussion of why a.T is better than t(a) or +a.

More information about the Numpy-discussion mailing list