hi everybody welcome back in this video we're going to cover several important topics in numpy starting with understanding array dimensions and reshaping numpy rays this is a very important topic especially in deep learning because the data we're going to process in neural networks often needs to be reshaped at various stages in the processing pipeline we're going to cover this topic in more detail in future videos when we start working with keras and tensorflow directly but it's important to establish a solid foundation of these concepts early on so we're going to begin by defining the array
info function that we introduced in the previous notebook and notice that we've added an additional print statement to this function which prints out the dimension of the input array we're going to start by working through several examples of reshaping data using the reshape function in numpy and notice first that the reshape function can be called using either syntax below in this notebook we'll be using the dot notation which allows us to use an existing numpy array to call the reshape method in which we specify a tuple for the new shape of the array the most
important thing to remember here is that reshaping a numpy array changes the shape of the array without altering the data itself and as we'll see below we can even change the number of dimensions in the array as long as the total number of data elements remains constant in this first example we're going to create a one-dimensional array using the a range function that contains the integers 1 through 12 as shown below notice that the shape of the array is indicated by the tuple 12 comma and that the dimension of the array is just one all
arrays in numpy are defined by a tuple where each component of the tuple is referred to as an axis so this one-dimensional array has just one axis also notice that a0 corresponds to the first element of the array so next let's use the reshape function to reshape this one-dimensional array into a two-dimensional array with one row and 12 columns as shown below in this case the tuple that defines the array is 1 comma 12 where the 1 corresponds to the first axis and the 12 corresponds to the second axis so the array has two dimensions
and notice that when we print a0 we can now see that this corresponds to the data along the first axis which in this case is the entire array from 1 to 12. when working with arrays we often describe the first dimension as being the rows of an array and the second dimension is being associated with the columns of an array this is a helpful mnemonic for the first two dimensions which correspond to the axis zero and axis one respectively but beyond that it becomes more abstract and in higher dimensions we simply refer to them as
axes it's worth pointing out at this point that the word dimension is an overloaded term whose usage depends on the context so for example when we're referring to a two-dimensional array which can be represented as a matrix we can refer to the array as having two dimensions or two axes but the word dimension is also used specifically in mathematical contexts to describe the length along a particular dimension or axis so in some cases we use the word dimension to describe the number of axes and in other contexts we use the word dimension to describe the
number of elements along a particular dimension or axis in the next section when we introduce tensors we'll see that the word dimension is specifically used to describe the number of axes in the tensor also referred to as the rank whereas the number of elements along any particular axis is more commonly referred to as the length of an axis so we just wanted to emphasize at this point that the use of the term dimension can sometimes be confusing but once you understand that it's an overloaded term it becomes much easier to sort out the terminology depending
on the context in the next example we're demonstrating that we can also use the reshape function to achieve the same result and instead of specifying explicitly the second dimension which is the number of columns you can just indicate a -1 which will create a single row with the appropriate number of columns so sometimes this can be convenient when you're working with a large amount of data we can also reshape the array to be 12 by 1 which would be 12 rows and one column and notice now that the way we index into the array is
different so a0 now refers to the first row in the array which in this case is just 1. so let's take a look at one more example below where we're going to reshape the array to be three by four because this array has twelve elements other possible transformations include four by three two by six and six by two since all of these are factors of 12. next we're going to take a look at working with multi-dimensional arrays with more than two dimensions but the concept is still the same and we'll see that reshaping higher dimensional
arrays is no different than reshaping 2d arrays here we're defining a 3 by 5 by 2 array to emphasize that the first axis which is 3 corresponds to the outermost bracket and then the next axis which is 5 corresponds to the next set of brackets and then finally the last axis which is 2 corresponds to the number of scalar values within the innermost brackets in the second example below here we're reshaping this 3-dimensional array into a 2-dimensional array of three by ten and this is allowed since three and ten are both factors of thirty you
might say to yourself at this point why would we want to reshape data in these various ways and there's multiple answers to this arbitrarily reshaping data may or may not be meaningful for a particular data set but oftentimes in deep learning existing frameworks have a predefined shape for accepting various types of data so take for example images which have a height and a width and also one or more color channels the order in which this data is stored is important and it's also possible that in some stages in the processing that the image portion of
the data may need to be represented as two-dimensional arrays or collapsed into a single one-dimensional array we'll see some examples of this later in the notebook and we'll also cover this in much more detail later in the course but we just wanted to provide some motivation at this stage for why it may be necessary to reshape data let's now talk about adding a dimension to a numpy array which can be accomplished in a number of ways here we're creating a one-dimensional array that contains the digits from one to nine and then we're reshaping that into
a three by 3 2d array next we're going to use the reshape function to reshape the array to be 1 by 3 by 3 which is effectively adding a new dimension to the array along the first axis another way to add a dimension to a numpy array is to use the expand dimms function in which we specify the array as the first argument and the axis along which we wish to create the new dimension as the second argument in this case we're going to specify axis equals zero and so here we achieve the same result
as we did above with the reshape function another approach we can use is to simply insert np dot new axis directly in the array at the desired axis location so here you can see that we're adding a new dimension along the first axis you might also notice that you could indicate none since new axis is mapped to none but it's preferred that you use new axis because it's more explicit for the same reason that we may need to expand the dimensions of an array it's also sometimes required to remove redundant dimensions within a numpy array
and we can do that with the squeeze function so in this first example we're creating a 1 by 3 by three array where the dimension along the first axis is redundant and so that dimension can be removed by the squeeze function by passing in the array as the first argument and then indicating which axis should be removed from the array notice that it only makes sense to remove redundant dimensions which do not contain any data in the next example we're demonstrating that it's not possible to remove an axis whose size is greater than one so
in this case here if we attempt to remove the second axis which has an index of 1 will get a value error as indicated below so now let's come back to the reshape function and talk about a special case that we referenced above instead of specifying two explicit dimensions you can specify a minus one for one dimension and then a specific value for the second dimension as long as that value is a factor of the original size of the array so in this case we have a one-dimensional array that contains values from zero to nine
and we're going to reshape that array into two columns which we can do by indicating a minus one for the number of rows instead of specifying five for the number of rows and the reshape function will automatically generate two columns and five rows another example is provided below where we specifically indicate that we want two rows and we specify -1 for the number of columns rather than indicating five explicitly so now let's talk about a reshaping example that's a little more concrete that has to do with flattening a portion of a numpy array let's suppose
that we have some two-dimensional data that's associated with images so in this case we're going to create three 4x4 two-dimensional numpy arrays and store them in a three by four by four three-dimensional numpy array so in this example we're notionally representing the 2d data associated with three separate images and now let's scroll down to take a look at this figure of a well-known convolutional neural network called vgg16 diagrams like this are often used to describe the architecture of a particular network so in this case at the far left we're showing the input image and then
to the right of that we're showing various layers within the network and notice that each layer has a size indicated as the data passes through the network from left to right the shape of the data changes as shown in the figure it's not important at this stage that we understand what these layers mean but we just wanted to emphasize that as the data is processed through the network the shape of the data is changing for example the data associated with the convolutional and max pulling layers in the first several stages of the network have a
two-dimensional structure along with the depth and the fully connected layers at the right-hand side of the network only have a depth so for example the data in the last max pooling layer which has a shape of seven by seven by five twelve is then flattened in the fully connected layer to the right which has the same number of data elements which is four thousand ninety six at this stage we're simply providing this as a notional example of how reshaping data is a common operation when working with neural networks so going back to our simple example
we can see below that we reshape the array to be 1 by 3 by 16 which is flattening the image portion of the data into a one-dimensional array while maintaining the other dimensions again we'll cover this topic in much more detail later in the course but we just wanted to provide an example for why reshaping data is often necessary the next topic that we're going to cover is how to combine arrays which can be accomplished with a few different methods in numpy the first method we're going to take a look at is the concatenate function
it takes two or more numpy arrays as input along with the axis for which the concatenation is to be performed all the arrays must have the same dimension except for the dimension corresponding to the specified axis in the first example below we're going to create a 2x3 numpy array and a 1 by 3 numpy array and then we're going to concatenate these two arrays along the first axis to create a 3x3 array notice that we could have specified more than just two arrays as long as all of the arrays have the same dimension other than
the axis specified for concatenation next we're going to take a look at two other types of functions that allow us to stack arrays either horizontally or vertically which is a little more specific but also more convenient since you don't have to specify the axis stacking arrays horizontally is accomplished with the h-stack function which takes as input a tuple of arrays to be stacked this amounts to concatenating arrays along the second axis unless the arrays are one-dimensional in which case they are stacked along the first axis in this first example we're creating a two by three
array and a two by four array and we're using h stack to combine those two arrays into a two by seven array as shown below in the next example we're creating two three by one arrays and we're combining those horizontally to create a three by two array so as you can see stacking arrays in this way is very convenient and easy to use next let's take a look at v-stack to stack arrays vertically and notice that the syntax is exactly the same as h-stack in the first example we're going to create two 1d arrays and
vertically stack them as shown below to create a two by three array and then next going back to one of our previous examples where we created a three by four by four array we're going to show how we can reconstruct that in a different manner using v stack so first we're going to create three one by four arrays and then we're going to vertically stack those to create a three by four by four array although the concatenate function is a little more general h-stack and v-stack are very convenient and easy to use because you only
need to supply the input arrays so that's all we wanted to cover in this video in the next video coming up we'll cover three additional topics in numpy which include element-wise operations linear algebra and array statistics thanks again and we'll see you soon