Difference in numpy np.zeros((1,2)) vs np.zeros((2,)) - python

I am stuck in this question. Can anybody explain me the difference between these two?
np.zeros ((1,2))
which yields
[[0. 0.]]
and
np.zeros((2,))
which yields
[0. 0.]

For each element in the main argument of np.zeros the function will add a new dimension to the output vector.
Your first code np.zeros ((1,2)) yields an array with two dimensions, one element in the first dimension and two elements in the second dimension, thus
[[0.]
[0.]]
The second piece of code has only one element in the main argument, which is translated to "one single dimension, two elements in that dimension". Thus, the output to your np.zeros((2,)) will be the same as the one for np.zeros(2):
array([0., 0.])
You could try with a third dimension to see it further:
np.zeros((1,2,1))
array([[[0.],
[0.]]])
I short, each square bracket adds to a new dimension based on the elements in the first argument of the function np.zeros.

Here's how I think about it.
This answer helpfully points out that "rows" and "columns" aren't exact parallels for NumPy arrays, which can have n dimensions. Rather, each dimension, or axis, is represented by a number (the size, how many members it has) and in notation by an additional pair of square brackets.
So a 1-dimensional array of size 5 isn't a row or a column, just a 1-dimensional array. When you initialise np.zeros ((1,2)) your first dimension has size 1, and your second size 2, so you get a 1 x 2 matrix with two pairs of brackets. When you call np.zeros((2,)) it's just one dimension of size two, so you get array([0., 0.]). I also find this confusing - hope it makes sense!

In the first, the items would be indexed as [0][0] and [0][1], and in the second, the items would be indexed by [0] and [1].
A shape of (1,2) means two dimensions, where the first dimensions happens to have only one index, i.e. it's a matrix with one row.

Related

Why do axes transpose upon indexing? [duplicate]

I have a 5 dimension array like this
a=np.random.randint(10,size=[2,3,4,5,600])
a.shape #(2,3,4,5,600)
I want to get the first element of the 2nd dimension, and several elements of the last dimension
b=a[:,0,:,:,[1,3,5,30,17,24,30,100,120]]
b.shape #(9,2,4,5)
as you can see, the last dimension was automatically converted to the first dimension.
why? and how to avoid that?
This behavior is described in the numpy documentation. In the expression
a[:,0,:,:,[1,3,5,30,17,24,30,100,120]]
both 0 and [1,3,5,30,17,24,30,100,120] are advanced indexes, separated by slices. As the documentation explains, in such case dimensions coming from advanced indexes will be first in the resulting array.
If we replace 0 by the slice 0:1 it will change this situation (since it will leave only one advanced index), and then the order of dimensions will be preserved. Thus one way to fix this issue is to use the 0:1 slice and then squeeze the appropriate axis:
a[:,0:1,:,:,[1,3,5,30,17,24,30,100,120]].squeeze(axis=1)
Alternatively, one can keep both advanced indexes, and then rearrange axes:
np.moveaxis(a[:,0,:,:,[1,3,5,30,17,24,30,100,120]], 0, -1)

Why can these arrays not be subtracted from each other? [duplicate]

I'm having some trouble understanding the rules for array broadcasting in Numpy.
Obviously, if you perform element-wise multiplication on two arrays of the same dimensions and shape, everything is fine. Also, if you multiply a multi-dimensional array by a scalar it works. This I understand.
But if you have two N-dimensional arrays of different shapes, it's unclear to me exactly what the broadcasting rules are. This documentation/tutorial explains that: In order to broadcast, the size of the trailing axes for both arrays in an operation must either be the same size or one of them must be one.
Okay, so I assume by trailing axis they are referring to the N in a M x N array. So, that means if I attempt to multiply two 2D arrays (matrices) with equal number of columns, it should work? Except it doesn't...
>>> from numpy import *
>>> A = array([[1,2],[3,4]])
>>> B = array([[2,3],[4,6],[6,9],[8,12]])
>>> print(A)
[[1 2]
[3 4]]
>>> print(B)
[[ 2 3]
[ 4 6]
[ 6 9]
[ 8 12]]
>>>
>>> A * B
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: shape mismatch: objects cannot be broadcast to a single shape
Since both A and B have two columns, I would have thought this would work. So, I'm probably misunderstanding something here about the term "trailing axis", and how it applies to N-dimensional arrays.
Can someone explain why my example doesn't work, and what is meant by "trailing axis"?
Well, the meaning of trailing axes is explained on the linked documentation page.
If you have two arrays with different dimensions number, say one 1x2x3 and other 2x3, then you compare only the trailing common dimensions, in this case 2x3. But if both your arrays are two-dimensional, then their corresponding sizes have to be either equal or one of them has to be 1. Dimensions along which the array has size 1 are called singular, and the array can be broadcasted along them.
In your case you have a 2x2 and 4x2 and 4 != 2 and neither 4 or 2 equals 1, so this doesn't work.
From http://cs231n.github.io/python-numpy-tutorial/#numpy-broadcasting:
Broadcasting two arrays together follows these rules:
If the arrays do not have the same rank, prepend the shape of the lower rank array with 1s until both shapes have the same length.
The two arrays are said to be compatible in a dimension if they have the same size in the dimension, or if one of the arrays has size 1 in that dimension.
The arrays can be broadcast together if they are compatible in all dimensions.
After broadcasting, each array behaves as if it had shape equal to the elementwise maximum of shapes of the two input arrays.
In any dimension where one array had size 1 and the other array had size greater than 1, the first array behaves as if it were copied along that dimension
If this explanation does not make sense, try reading the explanation from the documentation or this explanation.
we should consider two points about broadcasting. first: what is possible. second: how much of the possible things is done by numpy.
I know it might look a bit confusing, but I will make it clear by some example.
lets start from the zero level.
suppose we have two matrices. first matrix has three dimensions (named A) and the second has five (named B). numpy tries to match last/trailing dimensions. so numpy does not care about the first two dimensions of B. then numpy compares those trailing dimensions with each other. and if and only if they be equal or one of them be 1, numpy says "O.K. you two match". and if it these conditions don't satisfy, numpy would "sorry...its not my job!".
But I know that you may say comparison was better to be done in way that can handle when they are devisable(4 and 2 / 9 and 3). you might say it could be replicated/broadcasted by a whole number(2/3 in out example). and i am agree with you. and this is the reason I started my discussion with a distinction between what is possible and what is the capability of numpy.

Understanding PyTorch Tensor Shape

I have a simple question regarding the shape of tensor we define in PyTorch. Let's say if I say:
input = torch.randn(32, 35)
This will create a matrix with 32 row and 35 columns.
Now when I define:
input2 = torch.randn(1,2,32, 35)
What can I say about the dimension of the new matrix input2?
How can I define the rows and columns here? I mean do I have two matrices with shapes 32*35 packed by the tensor?
I want to better understand the geometry behind this. Thanks.
Consider tensor shapes as the number of lists that a dimension holds. For instance, a tensor shaped (4, 4, 2) will have four elements, which will all contain 4 elements, which in turn have 2 elements.
The first holds 4 elements.
The second holds 4 elements.
The third dimension holds 2 elements.
Here's what the data would look like:
[[[0.86471446, 0.26302726],
[0.04137454, 0.00349315],
[0.06559607, 0.45617865],
[0.0219786, 0.27513594]],
[[0.60555118, 0.10853228],
[0.07059685, 0.32746256],
[0.99684617, 0.07496456],
[0.55169005, 0.39024103]],
[[0.55891377, 0.41151245],
[0.3434965, 0.12956237],
[0.74908291, 0.69889266],
[0.98600141, 0.8570597]],
[[0.7903229, 0.93017741],
[0.54663242, 0.72318166],
[0.6099451, 0.96090241],
[0.63772238, 0.78605599]]]
In other words, four elements of four elements of two elements.
Yes, that is correct. Your input2 tensor has a rank of 4. (Rank is the Dimension) and the bounds of each dimension are (1,2,32,35)
The first dimension can hold one element.
The second can hold two.
The third can hold 32 elements.
The forth dimension can hold 35
elements.
EDIT: I find it is useful to think of higher-dimensional arrays as a series of lists. In your case, a rank 4 tensor, would be a list of lists of lists of lists.

How to get the number of elemets in an np.array?

Suppose there is an array
(1) x=np.array([[1,2],[1,2],[1,2]])
and a second array
(2) y=np.array([[1],[1,2],[1,2,3]])
The command size(x) returns the total count of all elements along every axis. In this case 6. However, size(y) returns 3. This must be because numpy interprets (2) in this case as three elements (the three subarrays) along one axis, although shape(y) returns (3, ). My question is now: how can I get numpy to interpret (2) as an array with three axes, so that size(y) returns the total count of all atomic elemets, which is 6?
I don't think it's possible to get the number of elements from y without looping over the objects.
The problem is that the elements of y are not numbers, they are objects (lists). Numpy does not support lists of lists and therefore it stores it as a 1-dimensional array of objects. I don't think there are Numpy methods to get the total number of elements in y.

How to intepret the shape of the array in Python?

I am using a package and it is returning me an array. When I print the shape it is (38845,). Just wondering why this ','.
I am wondering how to interpret this.
Thanks.
Python has tuples, which are like lists but of fixed size. A two-element tuple is (a, b); a three-element one is (a, b, c). However, (a) is just a in parentheses. To represent a one-element tuple, Python uses a slightly odd syntax of (a,). So there is only one dimension, and you have a bunch of elements in that one dimension.
It sounds like you're using Numpy. If so, the shape (38845,) means you have a 1-dimensional array, of size 38845.
It seems you're talking of a Numpy array.
shape returns a tuple with the same size as the number of dimensions of the array. Each value of the tuple is the size of the array along the corresponding dimensions, or, as the tutorial says:
An array has a shape given by the number of elements along each axis.
Here you have a 1D-array (as indicated with a 1-element tuple notation, with the coma (as #Amadan) said), and the size of the 1st (and only dimension) is 38845.
For example (3,4) would be a 2D-array of size 3 for the 1st dimension and 4 for the second.
You can check the documentation for shape here: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.shape.html
Just wondering why this ','.
Because (38845) is the same thing as 38845, but a tuple is expected here, not an int (since in general, your array could have multiple dimensions). (38845,) is a 1-tuple.

Categories

Resources