Transpose of a non-square matrix (without using ndarray.transpose)

  • Context: Python 
  • Thread starter Thread starter Wrichik Basu
  • Start date Start date
  • Tags Tags
    Matrix Transpose
Click For Summary

Discussion Overview

The discussion revolves around defining the transpose of a non-square matrix in Python without using the built-in Numpy transpose function. Participants explore various methods and considerations related to matrix transposition, including general programming techniques applicable across different languages.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant expresses their challenge in defining the transpose of a non-square matrix and references their experience with arrays in Java.
  • Another participant explains that the Numpy transpose function does not alter the array in memory but changes how it is accessed.
  • There is a suggestion to swap indices in the assignment for transposing a matrix, which resolves an error encountered by a participant.
  • Some participants propose using the zip function as a method for transposing matrices, demonstrating its application with examples for both square and non-square matrices.
  • Concerns are raised about the dependency of the zip method on the size of the matrix, with suggestions for handling matrices of varying sizes.
  • One participant expresses a preference for using Numpy for matrix operations over manual implementations, citing efficiency and functionality.

Areas of Agreement / Disagreement

Participants exhibit a mix of agreement and disagreement regarding the best approach to transpose a non-square matrix. While some advocate for using the zip function, others emphasize the advantages of Numpy functions. The discussion remains unresolved on a single preferred method.

Contextual Notes

Participants note limitations related to the size of matrices when using certain methods, as well as the potential for confusion in indexing when implementing transposition manually.

Who May Find This Useful

This discussion may be useful for programmers and students interested in matrix operations, particularly those working with Python and seeking alternatives to built-in functions for educational or practical purposes.

Wrichik Basu
Science Advisor
Insights Author
Gold Member
Messages
2,186
Reaction score
2,694
While the prefix of the thread is Python, this could be easily generalised to any language.

It is absolutely not the first time I am working with an array, but definitely the first time I am facing the task of defining the transpose of a non-square matrix. I have worked so much with arrays in Java, but unfortunately this simple yet tricky problem never came to my mind.

Numpy has a transpose function. But without using that, how can you define the transpose of a general m x n matrix, where ##m \neq n##?

Addition:
When I was learning Java, whenever I used any inbuilt function, I made it a habit to read up that documentation of that class, and then the class itself (from NetBeans, I could open the inbuilt classes). Similarly, in PyCharm, I navigated to the Numpy module, and opened the _multiarray_umath.py script. For the transpose function, I found this:
Python:
    def transpose(self, *axes): # real signature unknown; restored from __doc__
        """
        a.transpose(*axes)
        
            Returns a view of the array with axes transposed.
        
            For a 1-D array this has no effect, as a transposed vector is simply the
            same vector. To convert a 1-D array into a 2D column vector, an additional
            dimension must be added. `np.atleast2d(a).T` achieves this, as does
            `a[:, np.newaxis]`.
            For a 2-D array, this is a standard matrix transpose.
            For an n-D array, if axes are given, their order indicates how the
            axes are permuted (see Examples). If axes are not provided and
            ``a.shape = (i[0], i[1], ... i[n-2], i[n-1])``, then
            ``a.transpose().shape = (i[n-1], i[n-2], ... i[1], i[0])``.
        
            Parameters
            ----------
            axes : None, tuple of ints, or `n` ints
        
             * None or no argument: reverses the order of the axes.
        
             * tuple of ints: `i` in the `j`-th place in the tuple means `a`'s
               `i`-th axis becomes `a.transpose()`'s `j`-th axis.
        
             * `n` ints: same as an n-tuple of the same ints (this form is
               intended simply as a "convenience" alternative to the tuple form)
        
            Returns
            -------
            out : ndarray
                View of `a`, with axes suitably permuted.
        
            See Also
            --------
            ndarray.T : Array property returning the array transposed.
            ndarray.reshape : Give a new shape to an array without changing its data.
        
            Examples
            --------
            >>> a = np.array([[1, 2], [3, 4]])
            >>> a
            array([[1, 2],
                   [3, 4]])
            >>> a.transpose()
            array([[1, 3],
                   [2, 4]])
            >>> a.transpose((1, 0))
            array([[1, 3],
                   [2, 4]])
            >>> a.transpose(1, 0)
            array([[1, 3],
                   [2, 4]])
        """
        pass
As seen above, the only statement in the function is pass.

How does this function work? Or am I looking up the wrong function? (I have Python 3.7.4)
 
Last edited:
Technology news on Phys.org
As the function does something this can't be the function you actually call.
What it does is quite clever, however. It doesn't change anything in the array memory, it just swaps the way the array is addressed. Here is a description. It also has a link to a transpose code that does something.
 
mfb said:
As the function does something this can't be the function you actually call.
What it does is quite clever, however. It doesn't change anything in the array memory, it just swaps the way the array is addressed. Here is a description. It also has a link to a transpose code that does something.
That is an interesting way to do the job, and it answers the second part of my question. I also found that the numpy.swapaxes() function does the same thing. But any idea how to do the same job without using any function?

The problem basically arises because for non-square matrices, we can no longer write ##a^T_{ij} \ = \ a_{ji}##.
 
Wrichik Basu said:
The problem basically arises because for non-square matrices, we can no longer write ##a^T_{ij} \ = \ a_{ji}##.
Why do you say that?
 
marcusl said:
Why do you say that?
Consider the following code:
Python:
>>>a = np.array([[2, 3, 4], [5, 6, 7]])
>>>m = np.size(a,0)
>>>n = np.size(a,1)
>>>b = np.empty((n,m))
>>>for i in range(0,m):
...    for j in range(0,n):
...        b[i][j] = a[j][i]
...
This returns the following error:
1567089496443.png

But this runs properly once ##a## is a square matrix.
 
I think you've got your axes confused. Have you tried swapping i and j on both sides of the assignment in line 7?
 
Ibix beat me to it...
 
Ibix said:
I think you've got your axes confused. Have you tried swapping i and j on both sides of the assignment in line 7?
Maybe I had lost my mind, :headbang: yes that solves the problem.
 
Wrichik Basu said:
Maybe I had lost my mind, :headbang: yes that solves the problem.
Don't worry about making stupid mistakes - you'll never stop making them. Worry about preparations to catch them when they happen - good debugging, testing and general QA. It's the mistakes of general understanding you can fix.

That said, one thing that could have helped you here is to name your variables in a different way. For example, call m and n size0 and size1, and i and j i0 and i1. Then when you wrote a[i1][i0] you'd probably have realized that was wrong. It's not always the right thing to do since sometimes you want to follow the conventions of wherever your maths comes from, but it's worth considering.
 
  • Like
Likes   Reactions: FactChecker, marcusl and Wrichik Basu
  • #10
Transpose of a matrix can be find easily by using zip function. For instance if you have 2x2 matrix you can use zip like this

Python:
xmatrix = [[1, 2],
           [3, 4]]

print(list(zip(xmatrix[0], xmatrix[1])))

and the result would be
Code:
[(1, 3), (2, 4)]

or for ##m≠n##
Python:
xmatrix = [[1, 2],
           [3, 4],
           [2, 7]]

print(list(zip(xmatrix[0], xmatrix[1], xmatrix[2])))

and it prints

Code:
[(1, 3, 2), (2, 4, 7)]

And finally

Python:
xmatrix = [[1, 2, 7, 8],
           [3, 4, 9, 0]]

print(list(zip(xmatrix[0], xmatrix[1])))

Code:
[(1, 3), (2, 4), (7, 9), (8, 0)]
 
  • Like
Likes   Reactions: Wrichik Basu
  • #11
Your code depends on the size of the matrix.
 
  • #12
mfb said:
Your code depends on the size of the matrix.
Well yes. But I think in most cases we know the size of it. I agree that, in general, it might not be very useful.

If we have different matrix sizes in our data, we can do it like this

Python:
xmatrix = [[1, 2, 7, 8],[3, 4, 9, 0]]
xmatrix1 = [[4,5],[1,2],[0,-10]]

def transpose(xmatrix):
  if len(xmatrix) == 2:
    return list(zip(xmatrix[0], xmatrix[1]))
  elif len(xmatrix) == 3:
    return list(zip(xmatrix[0], xmatrix[1], xmatrix[2]))

print(transpose(xmatrix))
print(transpose(xmatrix1))

I would not prefer this one if I had a huge amount of matrix data. But If I had couple matrices I would prefer zip.
 
  • #13
Arman777 said:
I would not prefer this one if I had a huge amount of matrix data.
I always prefer to work with Numpy matrices rather than the lists. Never having used lists in Java till now, I can most probably work without them, unless the data becomes huge and I would like to save memory space by creating variable-size lists rather than arrays with fixed size. The additional advantage is that I can use the functions of Numpy when I need them. For a large program where transpose is maybe just 0.01% of the total code, I would prefer to use ndarray.transpose() rather than create my own functions.
 
  • Like
Likes   Reactions: Arman777
  • #14
Wrichik Basu said:
I would prefer to use ndarray.transpose() rather than create my own functions.
That makes more sense indeed
 
  • #15
Arman777 said:
Transpose of a matrix can be find easily by using zip function. For instance if you have 2x2 matrix you can use zip like this

Python:
xmatrix = [[1, 2],
           [3, 4]]

print(list(zip(xmatrix[0], xmatrix[1])))
Better, using argument unpacking:
Python:
list(zip(*xmatrix))
This works for a matrix (list of lists) of any size.
 
  • Like
Likes   Reactions: Wrichik Basu, mfb and Arman777
  • #16
Thats great thanks a lot
 

Similar threads

  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 25 ·
Replies
25
Views
3K
  • · Replies 17 ·
Replies
17
Views
4K
  • · Replies 2 ·
Replies
2
Views
2K
Replies
2
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 29 ·
Replies
29
Views
4K
Replies
12
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K