Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generalizing matrix transpose in numpy

Tags:

python

numpy

Let a be a list in python.

a = [1,2,3]

When matrix transpose is applied to a, we get:

np.matrix(a).transpose()
matrix([[1],
        [2],
        [3]])

I am looking to generalize this functionality and will next illustrate what I am looking to do with the help of an example. Let b be another list.

b = [[1, 2], [2, 3], [3, 4]]

In a, the list items are 1, 2, and 3. I would like to consider each of [1,2], [2,3], and [3,4] as list items in b, only for the purpose of performing a transpose. I would like the output to be as follows:

array([[[1,2]],
       [[2,3]],
       [[3,4]]])

In general, I would like to be able to specify what a list item would look like, and perform a matrix transpose based on that.

I could just write a few lines of code to do the above, but my purpose of asking this question is to find out if there is an inbuilt numpy functionality or a pythonic way, to do this.

EDIT: unutbu's output below matches the output that I have above. However, I wanted a solution that would work for a more general case. I have posted another input/output below. My initial example wasn't descriptive enough to convey what I wanted to say. Let items in b be [1,2], [2,3], [3,4], and [5,6]. Then the output given below would be of doing a matrix transpose on higher dimension elements. More generally, once I describe what an 'item' would look like, I would like to know if there is a way to do something like a transpose.

Input: b = [[[1, 2], [2, 3]], [[3, 4], [5,6]]]
Output: array([[[1,2], [3,4]],
               [[2,3], [5,6]]])
like image 490
rsimha Avatar asked Mar 18 '13 17:03

rsimha


1 Answers

Your desired array has shape (3,1,2). b has shape (3,2). To stick an extra axis in the middle, use b[:,None,:], or (equivalently) b[:, np.newaxis, :]. Look for "newaxis" in the section on Basic Slicing.

In [178]: b = np.array([[1, 2], [2, 3], [3, 4]])

In [179]: b
Out[179]: 
array([[1, 2],
       [2, 3],
       [3, 4]])

In [202]: b[:,None,:]
Out[202]: 
array([[[1, 2]],

       [[2, 3]],

       [[3, 4]]])

Another userful tool is np.swapaxes:

In [222]: b = np.array([[[1, 2], [2, 3]], [[3, 4], [5,6]]])

In [223]: b.swapaxes(0,1)
Out[223]: 
array([[[1, 2],
        [3, 4]],

       [[2, 3],
        [5, 6]]])

The transpose, b.T is the same as swapping the first and last axes, b.swapaxes(0,-1):

In [226]: b.T
Out[226]: 
array([[[1, 3],
        [2, 5]],

       [[2, 4],
        [3, 6]]])

In [227]: b.swapaxes(0,-1)
Out[227]: 
array([[[1, 3],
        [2, 5]],

       [[2, 4],
        [3, 6]]])

Summary:

  • Use np.newaxis (or None) to add new axes. (Thus, increasing the dimension of the array)
  • Use np.swapaxes to swap any two axes.
  • Use np.transpose to permute all the axes at once. (Thanks to @jorgeca for pointing this out.)
  • Use np.rollaxis to "rotate" the axes.
like image 93
unutbu Avatar answered Oct 05 '22 04:10

unutbu