274

I use Python and NumPy and have some problems with "transpose":

import numpy as np
a = np.array([5,4])
print(a)
print(a.T)

Invoking a.T is not transposing the array. If a is for example [[],[]] then it transposes correctly, but I need the transpose of [...,...,...].

smci
  • 32,567
  • 20
  • 113
  • 146
thaking
  • 3,495
  • 8
  • 27
  • 33

15 Answers15

310

It's working exactly as it's supposed to. The transpose of a 1D array is still a 1D array! (If you're used to matlab, it fundamentally doesn't have a concept of a 1D array. Matlab's "1D" arrays are 2D.)

If you want to turn your 1D vector into a 2D array and then transpose it, just slice it with np.newaxis (or None, they're the same, newaxis is just more readable).

import numpy as np
a = np.array([5,4])[np.newaxis]
print(a)
print(a.T)

Generally speaking though, you don't ever need to worry about this. Adding the extra dimension is usually not what you want, if you're just doing it out of habit. Numpy will automatically broadcast a 1D array when doing various calculations. There's usually no need to distinguish between a row vector and a column vector (neither of which are vectors. They're both 2D!) when you just want a vector.

LukeC92
  • 121
  • 1
  • 11
Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • 3
    @thaking - I just used `np.arange` to quickly make a 1D array. It works exactly the same for `a = np.array([5,4])`. – Joe Kington May 10 '11 at 18:45
  • 3
    @thaking If you are new to numpy - keep in mind that the round brackets `()` do not indicate an additional dimension in numpy. If `a = np.arange(10)` then `a` is `array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])` as produced by `a.__repr__()`. This is a 1-dimensional (i.e. `a.ndim --> 1`) vector as indicated by the square brackets `[]`. The `array( ... )` is not seen when you do either `print(a)` or `a.__str__()`. – dtlussier May 11 '12 at 16:15
  • 9
    @JoeKington there is a situation that broadcasting of a 1D array is useful. Computing the distance between all 1D points in an array. Thanks to your solution one can do x - x[np.newaxis].T which gives the distance matrix – JuanPi Apr 25 '13 at 02:13
  • 7
    Personally, I find `np.vstack()` operation to be more explicit: `print np.vstack(a)`. – Alexander Pozdneev Sep 21 '16 at 09:08
  • MATLAB does have a concept of a 1D array/vector – Vass Oct 20 '16 at 14:01
  • 17
    It's not just matlab, but linear algebra has the concept of a row/column vector. Numpy is idiosyncratic to folks coming from a lot of places, not just matlab. – eric Dec 29 '18 at 16:15
  • I do plenty of signal analysis and I exclusively do linear algebra and this is a royal pain in the butt. – Ash Apr 10 '23 at 22:27
176

Use two bracket pairs instead of one. This creates a 2D array, which can be transposed, unlike the 1D array you create if you use one bracket pair.

import numpy as np    
a = np.array([[5, 4]])
a.T

More thorough example:

>>> a = [3,6,9]
>>> b = np.array(a)
>>> b.T
array([3, 6, 9])         #Here it didn't transpose because 'a' is 1 dimensional
>>> b = np.array([a])
>>> b.T
array([[3],              #Here it did transpose because a is 2 dimensional
       [6],
       [9]])

Use numpy's shape method to see what is going on here:

>>> b = np.array([10,20,30])
>>> b.shape
(3,)
>>> b = np.array([[10,20,30]])
>>> b.shape
(1, 3)
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
savagent
  • 2,114
  • 1
  • 13
  • 10
116

For 1D arrays:

a = np.array([1, 2, 3, 4])
a = a.reshape((-1, 1)) # <--- THIS IS IT

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

Once you understand that -1 here means "as many rows as needed", I find this to be the most readable way of "transposing" an array. If your array is of higher dimensionality simply use a.T.

Ulf Aslak
  • 7,876
  • 4
  • 34
  • 56
  • 7
    Note that this works only with vectors. If you have 2-dimensional array the operations `transpose` and `reshape` modify array in different ways (the resulting image shape is the same, but the elements are placed differently). – johndodo Feb 21 '17 at 10:21
  • 2
    Thanks for your remark. I see your point, but I think it distracts more than it clears up my answer because I do give a simple one-line solution to the exact question that @thaking frames. It's not about 2-d arrays, it's about 1-d arrays. Apples and pears here. – Ulf Aslak Feb 21 '17 at 10:52
  • 6
    Of course. Your answer is correct and elegant for this case, I never meant to criticize it. But given the question title ("Transposing a NumPy array") I suspect many visitors will come here looking for a more generic solution and I wanted to warn them that it is not applicable to 2D arrays. Otherwise your answer is correct and suitable given the OP's question. – johndodo Mar 07 '17 at 10:31
  • @UlfAslak, please update your answer that your approach is not generalizable to N-D array, it's always good to be clear up front as suggested by !johndodo, so that nobody should use your technique wrongly.!, the question here is for the right answer & not a liner.! – Anu Dec 11 '18 at 05:05
18

You can convert an existing vector into a matrix by wrapping it in an extra set of square brackets...

from numpy import *
v=array([5,4]) ## create a numpy vector
array([v]).T ## transpose a vector into a matrix

numpy also has a matrix class (see array vs. matrix)...

matrix(v).T ## transpose a vector into a matrix
Community
  • 1
  • 1
Brent Bradburn
  • 51,587
  • 17
  • 154
  • 173
15

numpy 1D array --> column/row matrix:

>>> a=np.array([1,2,4])
>>> a[:, None]    # col
array([[1],
       [2],
       [4]])
>>> a[None, :]    # row, or faster `a[None]`
array([[1, 2, 4]])

And as @joe-kington said, you can replace None with np.newaxis for readability.

ankostis
  • 8,579
  • 3
  • 47
  • 61
11

To 'transpose' a 1d array to a 2d column, you can use numpy.vstack:

>>> numpy.vstack(numpy.array([1,2,3]))
array([[1],
       [2],
       [3]])

It also works for vanilla lists:

>>> numpy.vstack([1,2,3])
array([[1],
       [2],
       [3]])
Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
  • 1
    @sandroscodelller, have you looked at the code underlying `vstack`? `np.concatenate([atleast_2d(_m) for _m in tup], 0)`. It splits the array into (1,1) arrays, and concatenates those! In the process it makes a copy, while all the reshape ones make a view. – hpaulj Mar 03 '19 at 20:57
  • @hpaulj True, but that applies only when you are doing the process from another np array. If you are using a vanilla list as input to vstack, there is no lack of performance at it's clearer. – Ivan Apr 20 '21 at 14:29
  • @Ivan, `vstack` does the same things when `tup` is a list of ints. It makes each into a 2d array. For any size list, it will be slower than `np.array(alist)[:,None]`. Or stick with a pure list approach, `[[i] for i in alist]`. – hpaulj Aug 28 '22 at 15:53
4

instead use arr[:,None] to create column vector

Andreas K.
  • 9,282
  • 3
  • 40
  • 45
Mohammed Awney
  • 1,292
  • 16
  • 21
3

You can only transpose a 2D array. You can use numpy.matrix to create a 2D array. This is three years late, but I am just adding to the possible set of solutions:

import numpy as np
m = np.matrix([2, 3])
m.T
Jean-Louis Mbaka
  • 1,604
  • 11
  • 16
3

Basically what the transpose function does is to swap the shape and strides of the array:

>>> a = np.ones((1,2,3))

>>> a.shape
(1, 2, 3)

>>> a.T.shape
(3, 2, 1)

>>> a.strides
(48, 24, 8)

>>> a.T.strides
(8, 24, 48)

In case of 1D numpy array (rank-1 array) the shape and strides are 1-element tuples and cannot be swapped, and the transpose of such an 1D array returns it unchanged. Instead, you can transpose a "row-vector" (numpy array of shape (1, n)) into a "column-vector" (numpy array of shape (n, 1)). To achieve this you have to first convert your 1D numpy array into row-vector and then swap the shape and strides (transpose it). Below is a function that does it:

from numpy.lib.stride_tricks import as_strided

def transpose(a):
    a = np.atleast_2d(a)
    return as_strided(a, shape=a.shape[::-1], strides=a.strides[::-1])

Example:

>>> a = np.arange(3)
>>> a
array([0, 1, 2])

>>> transpose(a)
array([[0],
       [1],
       [2]])

>>> a = np.arange(1, 7).reshape(2,3)
>>> a     
array([[1, 2, 3],
       [4, 5, 6]])

>>> transpose(a)
array([[1, 4],
       [2, 5],
       [3, 6]])

Of course you don't have to do it this way since you have a 1D array and you can directly reshape it into (n, 1) array by a.reshape((-1, 1)) or a[:, None]. I just wanted to demonstrate how transposing an array works.

Andreas K.
  • 9,282
  • 3
  • 40
  • 45
2

Another solution.... :-)

import numpy as np

a = [1,2,4]

[1, 2, 4]

b = np.array([a]).T

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

omotto
  • 1,721
  • 19
  • 20
2

There is a method not described in the answers but described in the documentation for the numpy.ndarray.transpose method:

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].

One can do:

import numpy as np
a = np.array([5,4])
print(a)
print(np.atleast_2d(a).T)

Which (imo) is nicer than using newaxis.

Amin Karbas
  • 562
  • 1
  • 7
  • 16
  • 1
    Great answer. It provides a solution that is both as simple and more general than the solutions directly targeting the single vector case. – user209974 Apr 24 '23 at 09:29
1

The name of the function in numpy is column_stack.

>>>a=np.array([5,4])
>>>np.column_stack(a)
array([[5, 4]])
tmarthal
  • 1,498
  • 19
  • 28
  • `column_stack` does `np.array(a, copy=False, subok=True, ndmin=2).T`. The `ndmin` turns `a` into a (1,n) shape. It's a bit faster than the `vstack` that others have suggested, but there's no need to bury that action in a `concatenate`. – hpaulj Aug 28 '22 at 16:02
1

I am just consolidating the above post, hope it will help others to save some time:

The below array has (2, )dimension, it's a 1-D array,

b_new = np.array([2j, 3j])  

There are two ways to transpose a 1-D array:


slice it with "np.newaxis" or none.!

print(b_new[np.newaxis].T.shape)
print(b_new[None].T.shape)

other way of writing, the above without T operation.!

print(b_new[:, np.newaxis].shape)
print(b_new[:, None].shape)

Wrapping [ ] or using np.matrix, means adding a new dimension.!

print(np.array([b_new]).T.shape)
print(np.matrix(b_new).T.shape)
Anu
  • 3,198
  • 5
  • 28
  • 49
0

As some of the comments above mentioned, the transpose of 1D arrays are 1D arrays, so one way to transpose a 1D array would be to convert the array to a matrix like so:

np.transpose(a.reshape(len(a), 1))
TheOriginalAlex
  • 148
  • 1
  • 5
0

To transpose a 1-D array (flat array) as you have in your example, you can use the np.expand_dims() function:

>>> a = np.expand_dims(np.array([5, 4]), axis=1)
array([[5],
       [4]])

np.expand_dims() will add a dimension to the chosen axis. In this case, we use axis=1, which adds a column dimension, effectively transposing your original flat array.

Josh Weston
  • 1,632
  • 22
  • 23