Is
a = [1, 2, 3]
x = numpy.array(a)
a matrix of 3 cols and 1 row? I know that x = numpy.array([a]) is a 1x4 matrix but i need the opossite.
I need to multiply two matrix but the first one is a list inserted into a numpy.array(a)
have not found the doc for a way to do a for and cicle throught a to add it to x.
Edit: I am working on linear regression so i need a nrows x 1 col, my original data is in a list and am using numpy dot() funtion to multiply and i need to transform my list int a matrix nrowsx 1 column.
Fixed the solution was to transpose x = numpy.array([a]) with x = x.transpose() and that gives me a nx1 matrix.
Thanks for the help given you helped me think.
It is a 1 dimensional array:
In [653]: x = np.array([1,2,3])
In [654]: x
Out[654]: array([1, 2, 3])
In [655]: x.shape
Out[655]: (3,)
In [656]: x.ndim
Out[656]: 1
The other is 2 dimensional:
In [657]: y = np.array([[1,2,3]])
In [658]: y
Out[658]: array([[1, 2, 3]])
In [659]: y.shape
Out[659]: (1, 3)
In [660]: y.ndim
Out[660]: 2
the transpose of y
In [661]: z = y.T
In [662]: z
Out[662]:
array([[1],
[2],
[3]])
In [663]: z.shape
Out[663]: (3, 1)
The transpose of x is the same as x
Some multiply options:
In [664]: np.dot(x,y)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-664-6849a5f7ad6c> in <module>()
----> 1 np.dot(x,y)
ValueError: shapes (3,) and (1,3) not aligned: 3 (dim 0) != 1 (dim 0)
Read np.dot for rules about the interaction of shapes. The key phrase is 'last dimension of x pairs the 2nd to the last of y'.
In [665]: np.dot(y,x)
Out[665]: array([14])
Here the (1,3) pairs with (3,) t- produce a (1,).
Element wise multiplication. Here broadcasting rules apply
In [666]: x*y
Out[666]: array([[1, 4, 9]])
(3,) with (1,3) -> (1,3)(1,3) -> (1,3)
In [667]: x*z
Out[667]:
array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
(3,) with (3,1) -> (1,3)(3,1) -> (3,3)
A handy way of changing the (3,) array into a (3,1) is with None (np.newaxis):
In [671]: x[:,None]
Out[671]:
array([[1],
[2],
[3]])
In [672]: np.dot(x[:,None],y)
Out[672]:
array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
(3,1) dot with (1,3) -> (3,3)
Related
Main Question:
Is it bad (perhaps in terms of computation time or memory) to using np.array([[1, 2, 3]]) everywhere instead of np.array([1, 2, 3])?
Motivation:
I come form a math background, so I like to think of things in terms of vectors and matrices. For example, I think of y = np.array([1, 2, 3]) as a row vector, or as a 1 X 3 matrix. However, numpy doesn't treat y quite like a 1 X 3 matrix. For instance, if we take a 2 X 3 matrix A = np.array([[1, 2, 3], [4, 5, 6]]) numpy will allow us to do the matrix multiplicationA # y even though the dimensions are (2 X 3) times (1 X 3) don't make sense mathematically.
On the other hand, y # A.T gives an error even though the dimensions (1 X 3) times (3 X 2) make sense.
So in conclusion np.array([1, 2, 3]) does not behave exactly as a matrix. However, from my experiments it seems that numpy does treat np.array([[1, 2, 3]]) as a bona fide 1 X 3 matrix. So if there are no downsides, I would prefer to use this version.
numpy has an old subclass np.matrix that makes sure everything has exactly 2 dimensions. But it is no longer recommended.
numpy tries to work equally well with 0,1,2, and more dimensions.
In [69]: A = np.array([[1,2,3],[4,5,6]])
In [70]: x = np.array([1,2,3])
In [71]: y = np.array([[1,2,3]])
In [72]: A.shape
Out[72]: (2, 3)
Matrix product of a (2,3) with (3,) resulting a (2,). It's docs say it expands the (3,) to (3,1), getting a (2,1) result, and then squeezing out that 1:
In [73]: A#x
Out[73]: array([14, 32])
The (2,3) with (1,3) transposed produces (2,1):
In [74]: A#y.T
Out[74]:
array([[14],
[32]])
(3,) with (3,2) => (2,):
In [78]: x#A.T
Out[78]: array([14, 32])
(1,3) with (3,2) => (1,3):
In [79]: y#A.T
Out[79]: array([[14, 32]])
How does your math intuition handle 3d or higher arrays? matmul/# handles them nicely. np.einsum does even better.
While you can create a (1,n) arrays, if it makes you more comfortable. But beware that you'll still end up with 1 or even 0d results.
For example with indexing:
In [80]: A
Out[80]:
array([[1, 2, 3],
[4, 5, 6]])
In [81]: A[1,:]
Out[81]: array([4, 5, 6])
In [82]: A[:,1]
Out[82]: array([2, 5])
In [83]: A[1,1]
Out[83]: 5
In [84]: A[1,1].shape
Out[84]: ()
In [85]: A[1,1].ndim
Out[85]: 0
or reduction along an axis:
In [86]: A.sum(axis=1)
Out[86]: array([ 6, 15])
though it's possible to retain dimensions:
In [87]: A.sum(axis=1, keepdims=True)
Out[87]:
array([[ 6],
[15]])
In [88]: A[[1],:]
Out[88]: array([[4, 5, 6]])
In [89]: A[:,[1]]
Out[89]:
array([[2],
[5]])
Another to keep in mind is that numpy operators most operation element-wise. The main exception being #. Where as in MATLAB A*B is matrix multiplication, and A.*B is element-wise. Add to that broadcasting, which allows us to add a (2,3) and (3,) array:
In [90]: A+x
Out[90]:
array([[2, 4, 6],
[5, 7, 9]])
Here (2,3) + (3,) => (2,3) + (1,3) => (2,3). The (3,) 1d array often behaves as a (1,3) or even (1,1,3) if needed. But expansion in the other direction has to be explicit.
In [92]: A / A.sum(axis=1) # (2,3) with (2,) error
Traceback (most recent call last):
File "<ipython-input-92-fec3395556f9>", line 1, in <module>
A / A.sum(axis=1)
ValueError: operands could not be broadcast together with shapes (2,3) (2,)
In [93]: A / A.sum(axis=1, keepdims=True) # (2,3) with (2,1) ok
Out[93]:
array([[0.16666667, 0.33333333, 0.5 ],
[0.26666667, 0.33333333, 0.4 ]])
In [94]: A / A.sum(axis=1)[:,None]
Out[94]:
array([[0.16666667, 0.33333333, 0.5 ],
[0.26666667, 0.33333333, 0.4 ]])
import numpy as np
arr = np.array([[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]])
def np2dOperations(arr):
a = arr[0:1]
print(a)
b = arr[1:2]
print(b)
c = arr[2:3]
print(c)
d = arr[3:4]
print(d)
e = np.matmul(a,c)
print(e, "e")
f = b*d
x = e.sum()
y = np.amax(f)
print(x)
print(y)
print(x-y)
return x-y
np2dOperations(arr)
my output:
[[1 1 2 2]]
[[1 1 2 2]]
[[3 3 4 4]]
[[3 3 4 4]]
Traceback (most recent call last):
File "/Users/bethanne/Documents/NumPy2DOperations.py", line 24, in <module>
np2dOperations(arr)
File "/Users/bethanne/Documents/NumPy2DOperations.py", line 14, in np2dOperations
e = np.matmul(a,c)
ValueError: shapes (1,4) and (1,4) not aligned: 4 (dim 1) != 1 (dim 0)
I keep getting the following error "ValueError: shapes (1,4) and (1,4) not aligned: 4 (dim 1) != 1 (dim 0)" even though arrays a and c are the same size. The result should be 16 from x-y. I tried using np.transpose on array a but that didn't work either. I am newer to programming with numpy and python so please explain what I am doing wrong. Thank you!
So you start with a 4x4 array:
In [17]: arr = np.array([[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]])
In [18]: arr
Out[18]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]])
In [19]: arr.shape
Out[19]: (4, 4)
Indexing with a slice retains the 2d shape:
In [20]: a = arr[0:1]
In [21]: a
Out[21]: array([[1, 1, 2, 2]])
In [22]: a.shape
Out[22]: (1, 4)
Indexing with a scalar reduces the dimensions by 1
In [23]: a1 = arr[0]
In [24]: a1
Out[24]: array([1, 1, 2, 2])
In [25]: a1.shape
Out[25]: (4,)
matmul for 1d arrays is clearly documented:
In [26]: np.matmul(arr[0],arr[1])
Out[26]: 10
In [27]:
In [27]: np.matmul(arr[0],arr[2])
Out[27]: 22
matmul for 2d arrays is also clearly documented, and the requirements clearly stated in the error:
In [28]: np.matmul(arr[0:1],arr[2:3])
Traceback (most recent call last):
File "<ipython-input-28-88ee2e80387e>", line 1, in <module>
np.matmul(arr[0:1],arr[2:3])
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 1 is different from 4)
matmul of a (1,4) with a (4,1) does work, producing the same result as the 1d "dot" - except the result is a (1,1) array:
In [29]: np.matmul(arr[0:1],arr[2:3].T)
Out[29]: array([[22]])
Elementwise multiplication:
In [30]: arr[1]*arr[3]
Out[30]: array([3, 3, 8, 8])
In [31]: arr[1:2]*arr[3:4]
Out[31]: array([[3, 3, 8, 8]])
and so on for your other expressions. In numpy there is a clear distinction between 1d arrays and 2d ones. A (n,) shaped array is different from a (1,n) or (n,1) shape, even though they can be reshaped to each other.
This question already has answers here:
Numpy multiply arrays into matrix (outer product)
(2 answers)
Closed 4 years ago.
I'm trying to create a 2x2 array from a size 2 vector x by doing matrix multiplication like x * x^T:
>>> x = np.array([2, 2])
>>> x
array([2, 2])
>>> np.matmul(x,x.T)
8
As you can see, this fails. I came up with this solution:
>>> m = np.matrix(x)
>>> m
matrix([[2, 2]])
>>> m.T
matrix([[2],
[2]])
>>> np.matmul(m.T, m)
matrix([[4, 4],
[4, 4]])
Which achieves what I want. But is there a better way to do this, preferrably without resorting to using np.matrix?
EDIT: Creating a 2x1 vector is not an option because of the context outside the question.
Use np.outer:
np.outer(x, x)
# array([[4, 4],
# [4, 4]])
Alternatively, increase x's dimension by 1 before calling np.matmul:
x = x[:, None] # x = x.reshape(-1, 1)
x.shape
# (2, 1)
x # x.T # (2,1) . (1,2) => (2,2)
# array([[4, 4],
# [4, 4]])
If you reshaped x, you can use the # operator to do the multiplication:
x = np.array([2, 2])
Xprime = x.reshape(len(x), 1)
print(Xprime # Xprime.T)
#[[4 4]
# [4 4]]
np.array([2, 2]) doesn't create a 2x1 vector, it creates a 2 vector. If you want a 2x1 matrix, you need np.array([[2], [2]]). Or you can create a 1x2 matrix with np.array([[2, 2]]) and then do np.matmul(x.T,x)
You do not have a 2x1 vector here, but a 1D vector. You can see that with:
> x.shape
(2,)
To actually create a 2x1 vector, add bracets:
> x = np.array([[2, 2]])
> x.shape
(1,2)
And now you have what you want with:
> np.matmul(x.T,x)
array([[4, 4],
[4, 4]])
or x.T#x in Python3.
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).
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