How to convert (5,) numpy array to (5,1)? - python

How to convert (5,) numpy array to (5,1)?
And how to convert backwards from (5,1) to (5,)?
What is the purpose of (5,) array, why is one dimension omitted? I mean why we didn't always use (5,1) form?
Does this happen only with 1D and 2D arrays or does it happen across 3D arrays, like can (2,3,) array exist?
UPDATE:
I managed to convert from (5,) to (5,1) by
a= np.reshape(a, (a.shape[0], 1))
but suggested variant looks simpler:
a = a[:, None] or a = a[:, np.newaxis]
To convert from (5,1) to (5,) np.ravel can be used
a= np.ravel(a)

A numpy array with shape (5,) is a 1 dimensional array while one with shape (5,1) is a 2 dimensional array. The difference is subtle, but can alter some computations in a major way. One has to be specially careful since these changes can be bull-dozes over by operations which flatten all dimensions, like np.mean or np.sum.
In addition to #m-massias's answer, consider the following as an example:
17:00:25 [2]: import numpy as np
17:00:31 [3]: a = np.array([1,2])
17:00:34 [4]: b = np.array([[1,2], [3,4]])
17:00:45 [6]: b * a
Out[6]:
array([[1, 4],
[3, 8]])
17:00:50 [7]: b * a[:,None] # Different result!
Out[7]:
array([[1, 2],
[6, 8]])
a has shape (2,) and it is broadcast over the second dimension. So the result you get is that each row (the first dimension) is multiplied by the vector:
17:02:44 [10]: b * np.array([[1, 2], [1, 2]])
Out[10]:
array([[1, 4],
[3, 8]])
On the other hand, a[:,None] has the shape (2,1) and so the orientation of the vector is known to be a column. Hence, the result you get is from the following operation (where each column is multiplied by a):
17:03:39 [11]: b * np.array([[1, 1], [2, 2]])
Out[11]:
array([[1, 2],
[6, 8]])
I hope that sheds some light on how the two arrays will behave differently.

You can add a new axis to an array a by doing a = a[:, None] or a = a[:, np.newaxis]
As far as "one dimension omitted", I don't really understand your question, because it has no end : the array could be (5, 1, 1), etc.

Use reshape() function
e.g.
open python terminal and type following:
>>> import numpy as np
>>> a = np.random.random(5)
>>> a
array([0.85694461, 0.37774476, 0.56348081, 0.02972139, 0.23453958])
>>> a.shape
(5,)
>>> b = a.reshape(5, 1)
>>> b.shape
(5, 1)

Related

Why does the shape remains same when I sum a square numpy array along either directions?

I was expecting the shape to be (1,3) when I sum along axis=0 i.e. rows. But the shape remains same in both cases. Why is that?
>>> arr = np.arange(9).reshape(3,3)
>>> arr
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> arr.sum(1)
array([ 3, 12, 21])
>>> arr.sum(1).shape
(3,)
>>> arr.sum(0)
array([ 9, 12, 15])
>>> arr.sum(0).shape
(3,)
numpy.sum returns:
An array with the same shape as a, with the specified axis removed.
With one axis removed in both cases, you are left with a singleton tuple.
2 axes - 1 specified axis = 1 axis
However, passing keepdims as True in both gives different shapes, retaining all the axes in the original array with a corresponding change of length along the specified axis:
>>> arr.sum(axis=0, keepdims=True)
array([[ 9, 12, 15]])
>>> arr.sum(axis=1, keepdims=True)
array([[ 3],
[12],
[21]])
Because summing along the axis of a ND array yields a (N-1)D array. This makes sense if you consider that
np.sum([1,2,3]) == 6 # a 0D 'array'
If you want to turn your arr.sum(1) into a (1, 3) or (3, 1) 2D array, then use
s = arr.sum(0)[np.newaxis, :] # (1, 3)
or
s = arr.sum(1)[:, np.newaxis] # (3, 1)
According to the documentation this is what you'll get:
Returns:
sum_along_axis : ndarray
An array with the same shape as a, with the specified axis removed. If a is a 0-d array, or if axis is None, a scalar is returned. If an output array is specified, a reference to out is returned.
The shape of arr is indeed (3,3) and is two-dimensional. If you remove one axis you'll be left with a shape of (3,) - which is one-dimensional.
An array with shape (1,3) still has two axes.
numpy.arrays have a logic which is not the same than Matlab or even mathematics. From here :
Handling of vectors (one-dimensional arrays) For array, the vector
shapes 1xN, Nx1, and N are all different things. Operations like
A[:,1] return a one-dimensional array of shape N, not a
two-dimensional array of shape Nx1. Transpose on a one-dimensional
array does nothing.
Numpy story began not with linear algebra, so a one dimension object is always horizontal, cannot be transposed, an so on. It is confusing first time with a different background, but with a lot advantages in other fields. in numpy
2-dim arrays are lines (dim0) of columns(dim1), like for matrix, but selecting a line or a column return always ... a line !
As an example :
In [1]: m=np.arange(6).reshape(3,2)
In [2]: m
Out[2]:
array([[0, 1],
[2, 3],
[4, 5]])
In [3]: m[0,:]
Out[3]: array([0, 1])
In [4]: m[:,0]
Out[4]: array([0, 2, 4])
This convention accepted, nothing is very difficult.

when use * about numpy.array and numpy.matrix

I have two numpy arrays:
a = np.array([1, 2, 3]).reshape(3, 1)
b = np.array([4, 5]).reshape(2,1)
When I use a*b.T, I am thinking a wrong output because there is a difference in their shapes (using * performs element-wise multiplication for an array).
But the result returns Matrix multiplication, like this:
[[ 4, 5],
[ 8, 10],
[12, 15]]
# this shape is (3, 2)
Why does it work like this?
Your a * b.T is element multiplication, and works because of broadcasting. Addition, and many other binary operations work with this pair of shapes.
a is (3,1). b.T is (1,2). Broadcasting combines (3,1) with (1,2) to produce (3,2). The size 1 dimension is adjusted to match the other non-zero dimension.
Unless you make arrays with np.matrix, * does not perform mathematical matrix multiplication. np.dot is used to perform that (# and np.einsum also do this).
With this particular combination of shapes, the dot product is the same. np.outer(a,b) also produces this, the mathematical outer product. np.dot matches the last dimension of a with the 2nd to the last dimension of b.T. In this case they are both 1. dot is more interesting when the shared dimension has multiple items, producing the familiar sum of products.
In [5]: np.dot(a, b.T)
Out[5]:
array([[ 4, 5],
[ 8, 10],
[12, 15]])
'outer' addition:
In [3]: a + b.T
Out[3]:
array([[5, 6],
[6, 7],
[7, 8]])
It may help to look at a and b like this:
In [7]: a
Out[7]:
array([[1],
[2],
[3]])
In [8]: b
Out[8]:
array([[4],
[5]])
In [9]: b.T
Out[9]: array([[4, 5]])
I generally don't use matrix to talk about numpy arrays unless they are created with np.matrix, or more frequently scipy.sparse. numpy arrays can be 0d, 1d, 2d and higher. I pay more attention to the shape than the names.

Transforming a row vector into a column vector in Numpy

Let's say I have a row vector of the shape (1, 256). I want to transform it into a column vector of the shape (256, 1) instead. How would you do it in Numpy?
you can use the transpose operation to do this:
Example:
In [2]: a = np.array([[1,2], [3,4], [5,6]])
In [5]: a.shape
Out[5]: (3, 2)
In [6]: a_trans = a.T #or: np.transpose(a), a.transpose()
In [8]: a_trans.shape
Out[8]: (2, 3)
In [7]: a_trans
Out[7]:
array([[1, 3, 5],
[2, 4, 6]])
Note that the original array a will still remain unmodified. The transpose operation will just make a copy and transpose it.
If your input array is rather 1D, then you can promote the array to a column vector by introducing a new (singleton) axis as the second dimension. Below is an example:
# 1D array
In [13]: arr = np.arange(6)
# promotion to a column vector (i.e., a 2D array)
In [14]: arr = arr[..., None] #or: arr = arr[:, np.newaxis]
In [15]: arr
Out[15]:
array([[0],
[1],
[2],
[3],
[4],
[5]])
In [12]: arr.shape
Out[12]: (6, 1)
For the 1D case, yet another option would be to use numpy.atleast_2d() followed by a transpose operation, as suggested by ankostis in the comments.
In [9]: np.atleast_2d(arr).T
Out[9]:
array([[0],
[1],
[2],
[3],
[4],
[5]])
We can simply use the reshape functionality of numpy:
a=np.array([[1,2,3,4]])
a:
array([[1, 2, 3, 4]])
a.shape
(1,4)
b=a.reshape(-1,1)
b:
array([[1],
[2],
[3],
[4]])
b.shape
(4,1)
Some of the ways I have compiled to do this are:
>>> import numpy as np
>>> a = np.array([1, 2, 3], [2, 4, 5])
>>> a
array([[1, 2],
[2, 4],
[3, 5]])
Another way to do it:
>>> a.T
array([[1, 2],
[2, 4],
[3, 5]])
Another way to do this will be:
>>> a.reshape(a.shape[1], a.shape[0])
array([[1, 2],
[3, 2],
[4, 5]])
I have used a 2-dimensional array in all of these problems, the real problem arises when there is a 1-dimensional row vector which you want to columnize elegantly.
Numpy's reshape has a functionality where you pass the one of the dimension (number of rows or number of columns) you want, numpy can figure out the other dimension by itself if you pass the other dimension as -1
>>> a.reshape(-1, 1)
array([[1],
[2],
[3],
[2],
[4],
[5]])
>>> a = np.array([1, 2, 3])
>>> a.reshape(-1, 1)
array([[1],
[2],
[3]])
>>> a.reshape(2, -1)
...
ValueError: cannot reshape array of size 3 into shape (2,newaxis)
So, you can give your choice of 1-dimension without worrying about the other dimension as long as (m * n) / your_choice is an integer.
If you want to know more about this -1, head over to:
What does -1 mean in numpy reshape?
Note: All these operations return a new array and do not modify the original array.
You can use reshape() method of numpy object.
To transform any row vector to column vector, use
array.reshape(-1, 1)
To convert any column vector to row vector, use
array.reshape(1, -1)
reshape() is used to change the shape of the matrix.
So if you want to create a 2x2 matrix you can call the method like a.reshape(2, 2).
So why this -1 in the answer?
If you dont want to explicitly specify one dimension(or unknown dimension) and wants numpy to find the value for you, you can pass -1 to that dimension. So numpy will automatically calculate the the value for you from the ramaining dimensions. Keep in mind that you can not pass -1 to more than one dimension.
Thus in the first case(array.reshape(-1, 1)) the second dimension(column) is one(1) and the first(row) is unknown(-1). So numpy will figure out how to represent a 1-by-4 to x-by-1 and finds the x for you.
An alternative solutions with reshape method will be a.reshape(a.shape[1], a.shape[0]). Here you are explicitly specifying the diemsions.
Using np.newaxis can be a bit counterintuitive. But it is possible.
>>> a = np.array([1,2,3])
>>> a.shape
(3,)
>>> a[:,np.newaxis].shape
(3, 1)
>>> a[:,None]
array([[1],
[2],
[3]])
np.newaxis is equal to None internally. So you can use None.
But it is not recommended because it impairs readability
To convert a row vector into a column vector in Python can be important e.g. to use broadcasting:
import numpy as np
def colvec(rowvec):
v = np.asarray(rowvec)
return v.reshape(v.size,1)
colvec([1,2,3]) * [[1,2,3], [4,5,6], [7,8,9]]
Multiplies the first row by 1, the second row by 2 and the third row by 3:
array([[ 1, 2, 3],
[ 8, 10, 12],
[ 21, 24, 27]])
In contrast, trying to use a column vector typed as matrix:
np.asmatrix([1, 2, 3]).transpose() * [[1,2,3], [4,5,6], [7,8,9]]
fails with error ValueError: shapes (3,1) and (3,3) not aligned: 1 (dim 1) != 3 (dim 0).

how to understand empty dimension in python numpy array?

In python numpy package, I am having trouble understanding the situation where an ndarray has the 2nd dimension being empty. Here is an example:
In[1]: d2 = np.random.rand(10)
In[2]: d2.shape = (-1, 1)
In[3]: print d2.shape
In[4]: print(d2)
In[5]: print d2[::2, 0].shape
In[6]: print d2[::2, 0]
Out[3]:(10, 1)
Out[4]:
[[ 0.12362278]
[ 0.26365227]
[ 0.33939172]
[ 0.91501369]
[ 0.97008342]
[ 0.95294087]
[ 0.38906367]
[ 0.1012371 ]
[ 0.67842086]
[ 0.23711077]]
Out[5]: (5,)
Out[6]: [ 0.12362278 0.33939172 0.97008342 0.38906367 0.67842086]
My understanding is that d2 is a 10 rows by 1 column ndarray.
Out[6] is obviously a 1 by 5 array, how can the dimensions be (5,) ?
What does the empty 2nd dimension mean?
Let me just give you one example that illustrate one important difference.
d1 = np.array([1,2,3,4,5]) # array([1, 2, 3, 4, 5])
d1.shape -> (5,) # row array.
d1.size -> 5
# Note: d1.T is the same as d1.
d2 = d1[np.newaxis] # array([[1, 2, 3, 4, 5]]). Note extra []
d2.shape -> (1,5)
d2.size -> 5
# Note: d2.T will give a column array
array([[1],
[2],
[3],
[4],
[5]])
d2.T.shape -> (5,1)
I also thought ndarrays would represent even 1-d arrays as 2-d arrays with a thickness of 1. Maybe because of the name "ndarray" makes us think high dimensional, however, n can be 1, so ndarrays can just have one dimension.
Compare these
x = np.array([[1], [2], [3], [4]])
x.shape
# (4, 1)
x = np.array([[1, 2, 3, 4]])
x.shape
#(1, 4)
x = np.array([1, 2, 3, 4])
x.shape
#(4,)
and (4,) means (4).
If I reshape x and back to (4), it comes back to original
x.shape = (2,2)
x
# array([[1, 2],
# [3, 4]])
x.shape = (4)
x
# array([1, 2, 3, 4])
The main thing to understand here is that indexing with an integer is different than indexing with a slice. For example, when you index a 1d array or a list with an integer you get a scalar but when you index with a slice, you get an array or a list respectively. The same thing applies to 2d+ arrays. So for example:
# Make a 3d array:
import numpy as np
array = np.arange(60).reshape((3, 4, 5))
# Indexing with ints gives a scalar
print array[2, 3, 4] == 59
# True
# Indexing with slices gives a 3d array
print array[:2, :2, :2].shape
# (2, 2, 2)
# Indexing with a mix of slices and ints will give an array with < 3 dims
print array[0, :2, :3].shape
# (2, 3)
print array[:, 2, 0:1].shape
# (3, 1)
This can be really useful conceptually, because sometimes its great to think of an array as a collection of vectors, for example I can represent N points in space as an (N, 3) array:
n_points = np.random.random([10, 3])
point_2 = n_points[2]
print all(point_2 == n_points[2, :])
# True

Python: Differentiating between row and column vectors

Is there a good way of differentiating between row and column vectors in numpy? If I was to give one a vector, say:
from numpy import *
v = array([1,2,3])
they wouldn't be able to say weather I mean a row or a column vector. Moreover:
>>> array([1,2,3]) == array([1,2,3]).transpose()
array([ True, True, True])
Which compares the vectors element-wise.
I realize that most of the functions on vectors from the mentioned modules don't need the differentiation. For example outer(a,b) or a.dot(b) but I'd like to differentiate for my own convenience.
You can make the distinction explicit by adding another dimension to the array.
>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a.transpose()
array([1, 2, 3])
>>> a.dot(a.transpose())
14
Now force it to be a column vector:
>>> a.shape = (3,1)
>>> a
array([[1],
[2],
[3]])
>>> a.transpose()
array([[1, 2, 3]])
>>> a.dot(a.transpose())
array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
Another option is to use np.newaxis when you want to make the distinction:
>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a[:, np.newaxis]
array([[1],
[2],
[3]])
>>> a[np.newaxis, :]
array([[1, 2, 3]])
Use double [] when writing your vectors.
Then, if you want a row vector:
row_vector = array([[1, 2, 3]]) # shape (1, 3)
Or if you want a column vector:
col_vector = array([[1, 2, 3]]).T # shape (3, 1)
The vector you are creating is neither row nor column. It actually has 1 dimension only. You can verify that by
checking the number of dimensions myvector.ndim which is 1
checking the myvector.shape, which is (3,) (a tuple with one element only). For a row vector is should be (1, 3), and for a column (3, 1)
Two ways to handle this
create an actual row or column vector
reshape your current one
You can explicitly create a row or column
row = np.array([ # one row with 3 elements
[1, 2, 3]
]
column = np.array([ # 3 rows, with 1 element each
[1],
[2],
[3]
])
or, with a shortcut
row = np.r_['r', [1,2,3]] # shape: (1, 3)
column = np.r_['c', [1,2,3]] # shape: (3,1)
Alternatively, you can reshape it to (1, n) for row, or (n, 1) for column
row = my_vector.reshape(1, -1)
column = my_vector.reshape(-1, 1)
where the -1 automatically finds the value of n.
I think you can use ndmin option of numpy.array. Keeping it to 2 says that it will be a (4,1) and transpose will be (1,4).
>>> a = np.array([12, 3, 4, 5], ndmin=2)
>>> print a.shape
>>> (1,4)
>>> print a.T.shape
>>> (4,1)
If you want a distiction for this case I would recommend to use a matrix instead, where:
matrix([1,2,3]) == matrix([1,2,3]).transpose()
gives:
matrix([[ True, False, False],
[False, True, False],
[False, False, True]], dtype=bool)
You can also use a ndarray explicitly adding a second dimension:
array([1,2,3])[None,:]
#array([[1, 2, 3]])
and:
array([1,2,3])[:,None]
#array([[1],
# [2],
# [3]])
You can store the array's elements in a row or column as follows:
>>> a = np.array([1, 2, 3])[:, None] # stores in rows
>>> a
array([[1],
[2],
[3]])
>>> b = np.array([1, 2, 3])[None, :] # stores in columns
>>> b
array([[1, 2, 3]])
If I want a 1x3 array, or 3x1 array:
import numpy as np
row_arr = np.array([1,2,3]).reshape((1,3))
col_arr = np.array([1,2,3]).reshape((3,1)))
Check your work:
row_arr.shape #returns (1,3)
col_arr.shape #returns (3,1)
I found a lot of answers here are helpful, but much too complicated for me. In practice I come back to shape and reshape and the code is readable: very simple and explicit.
When I tried to compute w^T * x using numpy, it was super confusing for me as well. In fact, I couldn't implement it myself. So, this is one of the few gotchas in NumPy that we need to acquaint ourselves with.
As far as 1D array is concerned, there is no distinction between a row vector and column vector. They are exactly the same.
Look at the following examples, where we get the same result in all cases, which is not true in (the theoretical sense of) linear algebra:
In [37]: w
Out[37]: array([0, 1, 2, 3, 4])
In [38]: x
Out[38]: array([1, 2, 3, 4, 5])
In [39]: np.dot(w, x)
Out[39]: 40
In [40]: np.dot(w.transpose(), x)
Out[40]: 40
In [41]: np.dot(w.transpose(), x.transpose())
Out[41]: 40
In [42]: np.dot(w, x.transpose())
Out[42]: 40
With that information, now let's try to compute the squared length of the vector |w|^2.
For this, we need to transform w to 2D array.
In [51]: wt = w[:, np.newaxis]
In [52]: wt
Out[52]:
array([[0],
[1],
[2],
[3],
[4]])
Now, let's compute the squared length (or squared magnitude) of the vector w :
In [53]: np.dot(w, wt)
Out[53]: array([30])
Note that we used w, wt instead of wt, w (like in theoretical linear algebra) because of shape mismatch with the use of np.dot(wt, w). So, we have the squared length of the vector as [30]. Maybe this is one of the ways to distinguish (numpy's interpretation of) row and column vector?
And finally, did I mention that I figured out the way to implement w^T * x ? Yes, I did :
In [58]: wt
Out[58]:
array([[0],
[1],
[2],
[3],
[4]])
In [59]: x
Out[59]: array([1, 2, 3, 4, 5])
In [60]: np.dot(x, wt)
Out[60]: array([40])
So, in NumPy, the order of the operands is reversed, as evidenced above, contrary to what we studied in theoretical linear algebra.
P.S. : potential gotchas in numpy
It looks like Python's Numpy doesn't distinguish it unless you use it in context:
"You can have standard vectors or row/column vectors if you like. "
" :) You can treat rank-1 arrays as either row or column vectors. dot(A,v) treats v as a column vector, while dot(v,A) treats v as a row vector. This can save you having to type a lot of transposes. "
Also, specific to your code: "Transpose on a rank-1 array does nothing. "
Source:
Link
Here's another intuitive way. Suppose we have:
>>> a = np.array([1, 3, 4])
>>> a
array([1, 3, 4])
First we make a 2D array with that as the only row:
>>> a = np.array([a])
>>> a
array([[1, 3, 4]])
Then we can transpose it:
>>> a.T
array([[1],
[3],
[4]])
row vectors are (1,0) tensor, vectors are (0, 1) tensor. if using v = np.array([[1,2,3]]), v become (0,2) tensor. Sorry, i am confused.
The excellent Pandas library adds features to numpy that make these kinds of operations more intuitive IMO. For example:
import numpy as np
import pandas as pd
# column
df = pd.DataFrame([1,2,3])
# row
df2 = pd.DataFrame([[1,2,3]])
You can even define a DataFrame and make a spreadsheet-like pivot table.

Categories

Resources