Let us look at some operations on numpy arrays now.
So let's look at them from an example
standpoint. So it becomes easier for us. Imagine if I've created a numpy array like this. It's a
one dimensional array with four elements, 1234. And if I say, and this numpy array is stored
in a variable called a. Now, if I say a plus one here, if I say a plus one here, here, one is a
scalar, right? It's not a vector or it's not an array, right? So if, when I'm adding a scalar, what
happens is this one gets added to every element here. So one plus one becomes two, one
plus two becomes three, one plus three becomes four, one plus four becomes five. So when
you do a scalar addition to a matrix, so if you say 1234, which is actually an array, to this, if
you add one, right? This is an array to an array like this. If you add one, this one is added to
every element of the array. And what you get is this, right? So this is called the scalar
addition. Similarly, if you have this array a and this operator is nothing but the exponent
operator, right? This operator is nothing but the exponent operator. So when I do a star, star
two, what happens is it takes each of the elements of a and computes the square of the
element, because exponent two is nothing but square, right? So one square is one, two
square is four, three square is nine, four square is 16. So this is also an element wise
operation. If you notice, all these operations are element wise because they operate on each
element individually. Now, similarly, let's take a slightly different operation between arrays.
Now. So what is our a? Our A was one to an array which is like this. It's not a list, it's an
array, right? This is a numpy array, not a list. Okay? Now I'm saying B is NP ones, four plus
one. So what happens to B's b, I'm saying is NP ones four, which means it creates an array of
length four. Now I'm adding one to it, which means all of these values become two, right? All
of these values now become two. Now I'm saying a minus B. So what happens when I do a
minus B? What happens is one minus two is minus one, two minus two is zero. So what it's
doing is it's doing element wise subtraction, because both a and B are arrays right? Now,
and hence it's doing an element wise subtraction. Three minus two is one, four minus two, is
two. Now if I do a star B, remember here a and B are both arrays. When I do a star B, what
happens is it does component wise multiplication. This is called element wise
multiplication. So it multiplies one with two to give you two, two with two to give you four,
three with two to give you six, and four with two to give you eight. Right? So this is basically
addition and multiplication of arrays. This is basically addition and multiplication of arrays
of same size. Right? Now let's look at a slightly different variation. There is something called,
so when I say NP diagonal 1234, what, what do I get? I get basically a diagonal matrix which
is 123400. This is what I get. I get a matrix like this, a four cross four matrix which has four
rows and four columns. I get a matrix like this, right where the diagonal elements are 1234.
Let's assume this matrix is C. Now if I do C star C, what happens? It multiplies this matrix
with itself. It multiplies this matrix with itself. So some of you, or most of you I'm assuming,
have learned how to multiply two matrices. You basically take the first row, multiply with
the first column, and sum it up. Similarly, you take the first row, second column, and
multiply it up, so on and so forth. And when you multiply these two, what you get is a matrix
like this. You can actually try it manually and see it. The final matrix that you get here is
100-4009 and 60. This is what you get if you do C multiplied by C. And this is simple matrix
multiplication. This is simple matrix multiplication that most of us would have learned in a
10th grade or in 11th grade typically, right? So very simple matrix matrix multiplication.
Now I can do the same matrix matrix multiplication using two ways. One is C multiplied by
C, or I can say c dot c, because typically in mathematics, in linear algebra or matrix algebra,
we actually use the dot notation to multiply two matrices or two vectors in some cases. So c
dot C can also be used. The result is exactly the same. Okay, so this is matrix, matrix
multiplication. Now let's look at comparisons. Now imagine if I have two numpy arrays. My
first one umpire is 1234. My second numpy array is phi two two four. Now, if I say a double
equals to two, I'm trying to compare a and b, what it returns to me is now an array of length
four. Where it does, element wise comparison is one equals to five. No. And hence it is false.
Here, two equals to true true. Three equals to two false. Four equals to four true. So it is
doing an element wise comparison. When I do double equal to similarly, I can use other
operators like greater than a, greater than b. What it gives me is, is one greater than five
false. Two greater than two false. Because it's equal to three greater than two. Yes, it is true.
Four greater than two, false. Right. So this is how you can do it. So there is another thing
called element wise array comparisons. Right? Now let's look at it. So now I have three
arrays here, right? What I'm doing here is if you do Np array equal A and B, now what it
does. So this function is different. We are not using the double equal to sign here. We are
saying array equals now is A and B equal. No, they are not, right, because these two
elements are different and these two elements are different. So it will return false. What
about NP array equal A and C? So a and C element wise, they are the same, right? They're
exactly the same element wise. So it will return true. So if you want to compare whether all
elements of two arrays are equal or not, the best way is to use array equal. Okay, now let's
go and look at some simple logical operators. Again, very, very straightforward. Suppose if I
have two numpy arrays here, I'm saying that the data type is boolean, right? I'm giving a
vector, or I'm giving a list of ones and zeros, one representing true, zero representing false.
Now I can do basic logical operations like logical or logical and using these commands in Np,
or using these functions in Np, very, very simple. Nothing very fancy here. Okay, having said
that, now let's go and look at some slightly more interesting mathematical functions. Now
here I'm saying a equals to Np, arrange five, which means I get an array which looks like
this. I can say Np sine a. Then what it will do, it is compute sine theta, the trigonometric
function sine theta. Right. The trigonometric sine to each of these values and returns me an
array. Similarly, I can compute log, but remember, log of zero is not defined and hence it
returns minus infinity, right? Log of one is zero, log of two, log of three, log of four, right? So
you can apply functions like sine log or exponent. Exponent basically means e power x.
Okay? E is a special mathematical symbol which is called the base of natural logarithm. If
you don't know that, it's okay. We'll anyway encounter e a lot of times in probability
statistics and in machine learning in general. So we'll relearn this concept. So it's basically
doing e power x for each of the values. And Ep one is 2.7 118. Okay, so you can apply
mathematical functions like sine log exponent because they all are available in numpy
automatically for you. And it does element wise operations here. Okay, now let's look at
what happens if you're trying to, so this is a very fun thing. Imagine if I have a numpy array
of 0123, right? Because I'm saying NP, arrange four to this. If I try to add another numpy
array like this. Okay, it makes no sense, right? Can you add these two, can you add these two
arrays? You can't because they're not of the same size, because you could add this, this.
What about the rest of these two? There is nothing to add them with. So when you try to do
this, it says operands could not broadcast together with shapes. So one of them has a shape
of four, the other has a shape of two, and hence I am not able to add them. So it gives you
something called a value error when there is a shape mismatch between them, right? So
now let's look at some very basic commands that you can do. So we learned about reduce
functions, right? Reduce functions. Take a list or an iterable element or an iterable data
structure, and it returns some value of it. So here also we have some reductions. For
example, let's look at some of these very simple reductions. Suppose if I have an umpire
array, and if I say np sum, it sums up all of these elements and returns us the sum. Similarly,
if I have a matrix here, here I have a matrix which is one one, and two two. Now I can say
this matrix is called x. Now I can say x, dot, sum, axis equals to zero. When I say axis equals
to zero, what it does is it does column wise sum. When I say axis equals to zero, it does
column wise sum. So what it returns me is now an array which is three cross three, because
it is summing these columns, right? If I say axis equals to one, what happens then? So now I
have an array which is 1122. And when I say access equals to one, it does row by sums,
right? It does row by sum. So it sums one and one, it gives two, two, and two, it gives four. So
it returns us. So when I do an axis, y, sum, x dot, sum, axis equals to one, axe equals to one
means it's a row by sum, axis equals to zero means it's a column by sum, right? So now here
I get three, three. While for row, for column wise sum, I get three. Three, right? If I sum
these two, I get three. If I sum these two, I get three. So column wise. So if axis equals to
zero, I get this. If axis equals to one, I get this right. Now let's look at other simple
reductions. So for example, if I want to find the minimum element between all of them, the
minimum element is one. Whatever the maximum element, it is three. There are two other
very interesting functions called arg min and argmax. Let me explain what they are. So I
have an array like this. Now. 00:32 this is at index zero. This is at index one. These are
indices. These are indices, and this is my array. So when I said what is the minimum value?
It returned me one. This is the minimum value, right? Now if this is the minimum value, the
index that it is at is called the arg min, because again, we'll see this when we learn
optimization. It's a mathematical notation. Argmins are used in optimization a lot. Okay, so
that's where the terminology arg min comes from. Argmin basically says, at what index in
this array is my smallest element. So if you say x dot arg min, it returns zero. What about the
maximum element? This is the maximum element. And what is the index? It is at, it's at one.
So which means this becomes the argmax, right? So if you say x dot argmax, you get one,
because at index one you have the largest element, right? So Argmax and argument are
important. Anyway, we'll revisit them and we'll learn optimization later in this course.
Right? Similarly, you have some of these very, very simple functions. Like all, you can say NP
all. If all of them are true, it returns true. If any one of them is false, it returns false. Similarly,
NP any, what it does is if any one of them is true. So any is like logical. Or this is like logical
and intuitively so. If any one of them is true, it returns true, right? You can use the same any
and all for other things. For example, look at it here. Here I've created NP zeros 50 50, right?
So what am I creating? I'm creating a matrix of size, 50 rows and 50 columns where all the
elements are zero. Where all the elements are zero. Now I can say NP ne a not equal to zero,
which means is there any element which is not equals to zero? No, and hence it's false.
Similarly, you can put any boolean operation here. You can say NP all a equals to a. Of
course A is equals to a because every element of a is equal to every element of a, and hence
it returns true. Right. Let's look at slightly more interesting and more complicated stuff
here, okay? So let's assume I have this array, A, which is 1232 b, 2232 c. Six, four, five. Now
look at this. When I do this, I get a fairly big. So when I say a less than equal to b, what
happens then? A less than equal to b returns me an array which is. Is this less than equal to
this? Yes. True. Is this less than equal to this? True. Is this less than equal to this? True. Is
this less than equal to true? True. Right? And I'm doing logical operation of that with b less
than equal to c. Okay? Is b less than equal to c element wise? True. And when I do a logical.
And of both of these, what happens? I get true, true, true. And now I'm saying dot all. Of
course all of them are true. And hence you get a return value of true. So we can construct
very, very complex examples like this, again, based on what you need to do. So, literally, in
one line of code, you have tested whether every element of a is greater than, is less than
equal to b, and every element of b is less than equal to c, or not. Literally, in one line of code,
you have done the whole thing, which otherwise you would have to write a for loop
comparing them. Again, a for loop comparing these two and stuff like this. Now, you could
achieve all of that, literally, elegantly, in just one line of code. Okay? Now let's look at some
very simple things. Suppose if I have two arrays. Suppose I have an array like this, 1231,
right? If I compute x dot mean, which gives me the average value, which is 1.75. Similarly, I
can compute median. Now, if you do not understand what mean and median are, we
explained them in the exploratory data analysis chapter, okay? So don't worry what you do
if you don't. They are basically mathematical operations. Similarly, y is now an array. Y has
one, two, three and five, six, one. This is my y, right? Now, if I say compute the median of y
and axis equals to minus one, so when I say axis equals to minus one, it means the last axis.
Now, I have two axes here, right? My axis zero, my axis zero means columns. My axis one
means rows, right? My last axis is nothing but my rows, right? Now when I say find the
median, so what is the median of all these three numbers? Median of all these three
numbers. So even if I had said plus one or minus one, it's the same thing. It means by rows.
Right. What does this mean when I do the mean of all of them? So the median of all of them
is two. The median of all of these is five. Median is the central value. So you can compute
median on matrices using the access command. Similarly, there is something called a
standard deviation. Those of you who do not know what is standard deviation, please check
out our videos in the exploratory data analysis chapter where you'll understand them. And
again, it's a mathematical operation, it's a statistical operation to be precise. Okay, so numpy
helps you do all of these things. Now let's go and look at some data. So here I have, here I
have a very simple data. Here in the same folder, I have a file called populations txt. Okay, so
this population TXT has four columns of data. My first column is the ear. My second column
is the population of hairs or rabbits. Hair is nothing but another word for rabbit. Right?
Links is a type of wild cat and carrot, the population of carrots, the number of carrots that
are available. Let's assume in a given forest, these are the numbers for every year. These are
the numbers of rabbits, numbers of wild cats, number of carrots. Remember, your rabbits or
hairs eat your carrots and your links, which are your wild cats, eat your hairs or rabbits.
Okay, so whenever you see this number, like 77.4, e three, what it means is it is 77.4 into ten
power three. What is ten power? 3000. Right into thousand. So this is called the scientific
notation of storing numbers. So this is 77 400, right? So whenever any number is written e
three or e four, what e three means is it represents multiplied by ten power three, that's
what it represents. Okay, very simple. Now I have this table, I have this file. Now let me see
how I can load this file and do some simple operations. Okay, now in numpy, it's very
simple. I just have to say Np load text Populations txt. This whole file is loaded now. Now if I
try to print the data, it is actually stored in a numpy array for me. So each row becomes a
row in my table because it's in my array, literally. Right? Now what I can do here is, so the
transpose operation is an interesting operation. If you have a matrix like this, let me show
you the transpose operation. If you have a matrix like this, 123456. Let's assume this is a
matrix A. Now when I say a transpose, this is how it's written mathematically in the
program. It's written a dot t what it does is it takes the rows and converts them into
columns. So I took the first row and I converted into column. I took the first row, I converted
into column. Similarly, I'll take the second row, I'll convert into column, okay? So a
transpose is basically taking the rows and converting them into columns. Now remember,
look at it, this is basically two rows and three columns. So this will become three rows and
two columns. That's what transpose means, right? So now I can create four variables called
ear hairs, links and carrots, as D transpose. Right? Now, if I say print year, I get an array of
all the years, okay? Now let's try to operate on this data, do some basic operations, because
my first column, remember my first column of data is ear. Sorry, let me just write it. Ear
hairs, right? My links, I believe this is the spelling, right, okay, and carrots, right? Now what
I'm doing here in this function, what I'm doing here is I'm saying data, take all the rows.
That's what I mean here, take all the rows, but take from, so this is column zero, column one,
column two, column three, right? This is what my table looks like. So it's saying take all the
rows, but take from first column onwards up to the last column. So it's basically taking this
subset of my matrix, it's discarding the year. So what I have in my populations variable is
the actual populations of all these three species of plants or animals. Okay? This is for
carrots, this is for links, and this is for hairs. Now, if I want to do some simple computations
on it, suppose if I want to find the standard deviation of these populations, I can say
populations standard deviation. Access equals to zero. When I say access equals to zero,
what happens? It computes by column, not by row, by column. Basically means this column
represents hairs, this column represents links, and this column represents carrots, right?
And hence that's how you get it. Now if I want to find, so let's ask a question. Which species
has the highest population each year? Right? Then what do I want to do every year? These
are the three populations, right? So this is for year 1900, these are the three populations,
year 19, what? 19, one, so on and so forth. So if I do, if I do, and this is index zero, index one,
index two. Now I want to find out which of these three organisms, or plants or animals have
the highest population in a given year. What can I do? I can simply say argmax NP, argmax
populations, access equals to one. So what happens? As soon as I say access equals to one.
It's going to operate row wise. So it's going to take this row and say, and we are saying
Argmax, right? So it says which of these three is the largest value? So here, this is the largest
value, right? This is the largest value and the index of that is two. So it will return two. So
what I get, finally, is basically an array like this. See, this is a question, which species has the
highest population each year? Now I've just used my access equals to one. And Ardmax,
these are all stuff that we learned and now we are applying it to data. Very, very simple
example to answer a real world question. This is a fairly genuine question. In Numpy, there
is a very, very important and interesting concept called broadcasting. Let me explain you
what broadcasting means. Okay? Suppose I have an array like this. Now, when I add this
array, so this is a matrix, right? This is a matrix. It has four rows and three columns, right?
Four. Cross three to this. If I add one more array, which is again four rows and three
columns, what do I get? This is equivalent to adding these two is equivalent to the same
thing. It's equivalent to adding these two, right? It's exactly this. I've just copied it. What is
the final value that you get? The final value you get is this, because what it does, it does an
element wise addition. It does an element wise addition. So if you add these two, it is same
as, I'm just, see, this is same as this. This is exactly same as this. Okay, so adding these two is
same as this two. Exactly. Just copy paste. But overall it's equivalent to, because I'm doing
element wise sum, right? So you take this 20 plus one. So this value should be 21. So it's
element wise addition. Now comes the fun part. This is the obvious trivial part. Now comes
the fun part. Okay, imagine if I have a numpy array like this. If I have a numpy array like this.
Now I can add this to another numpy array, which is just zero, one, two, broadcasting.
Basically what it does is now it tries to adjust the second array. What it tries to do is it
replicates this array so as to fit this size, because the number of columns here is three here
also the number of columns is three here the number of rows are four. Here the number of
rows is one. So what it will do is it will simply, so this addition will be equivalent to, it will
replicate these number of rows. It had only one row initially, right? So it will create three
more rows and then it'll add up everything to result in the same thing. Right. Elegant. Now,
there is a third way. Imagine, see, if you notice when you replicate it twice, you exactly get,
these three rows are exactly the same. So what if I just have this row and I just have this
column. Sorry. I just have this column and this row. Now, when I try to add it, and if I say
replicate this three times and replicate this four times, when I say replicate this three times,
what happens is it creates this new matrix. This is the original matrix. It's now replicating
the same thing three times. When I say replicate this four times, it replicates this four times.
Now. And now when I add these two, I get the exact value. We'll see this with some code
example. This concept is called broadcasting. This whole concept is called broadcasting in
numpy. It's very, very unique to numpy, actually. Okay, now let's take an example. Okay, I'll
change this code slightly. So there is this function called tile, which will pile up these tiles,
right? It's literally like these tiles being piled up. Okay, so let's look at it. Let's look at an
example, right? So here I'm creating a numpy array, zero to 40 with intervals of ten, which
means now it creates 00:10 2030. This is the array that this part creates an array. It's a one
dimensional array, right? Now what I'm saying here is replicate this, replicate this three
comma, one, which means replicate this three times. Replicate this three times in terms of
rows. So when I replicate the same thing three times in the rows, what happens? I get this.
I'm replicating three times in the rows. What I get is this. In the column space, this three
basically means replicate it three times. So this three is the same as this three. These three
times I'm replicating. This one says replicate this only once. Right? And now what I get my
NP tile. When I print a, what I get is exactly this. What I get is exactly this. Now let's play
with this and change it a little. Okay, let me change this code also a little so that it becomes
easier for us to read it. Okay, let me just. So that I'm trying to make this more readable for
us. Okay, so let's print this. Okay, this is what I get because I'm replicating again, just to
quickly repeat myself, I have my original array, which is 00:10 2030. And it's saying
replicate three times in the rows. So I've replicated it once, twice, thrice in the columns. Just
replicate it once. So it's there only once. Now let me change it slightly. What happens if I just
change this to two? Sorry, not 21. Two. Okay, now what happens now? I get a slightly
different array. Okay, so now let's see. My original array was. 00:10 2030. This is the power
of the tile function. It basically tiles things up like putting one tile on top of other. Now here
I'm saying replicate this array. Replicate this array that I have three times in the rows. So
replicate it three times in the rows once, twice, twice. But in the columns also replicate it
twice. So which means now columns, it's replicated once and replicated twice. This is the
replication of twice in the columns. Right. And this is the replication of columns three times
here. So you can use tile to construct more and more complex tilings. See what happens in
tiles. You put one tile on top of other tile, on top of other tile next to another tile, next to
another tile, et cetera. Exactly. That's what we are doing. Right? So now let me go back and
change it to the original one because the rest of the code follows that line. Right? Now, again,
so this is my original array. Now if I transpose it, what do I get? I get. 00:10 2030 if you
notice, this is exactly what we have here. 00:10 2030 00:10 2030 00:10 2030 and I've
created this using so, and I'm saying a equals to a transpose. So this becomes my new a,
right. This becomes my a matrix. Now if I say let's create a new array, which is B. My b. My a
is exactly the one that we saw earlier. My b is zero, one, two, if you notice. What is my B? My
b is exactly this. My b is exactly this. This is my A and this is my b. That's what I'm defining
it. I'll keep coming back to this diagram. Okay, now if I say a plus B, what happens? Now,
remember, when I say a plus B, what's happening here is a is already of size. Three rows.
Sorry. Three columns. Right? I have column one, column two, column three, row one, row
two, row three, row four, right? And this is column one, column two, column three. When I
try to add these two, right? Because this matrix is of a much larger size and the columns, at
least are matching the columns here. There are three columns here. There are three
columns here. What it internally does is it replicates this three times like this. It replicates
this, sorry, four times because I have four rows and it adds them up. And this is the result I
get, right? So let's see the result that we get when you do that. All I'm doing here is I'm
taking my A. My B is this. I'm saying a plus B and I get what you expect, which is exactly this
result. Right. Now let's do something much more fun. So we have seen this case, right? So
there are three cases here. This case is the obvious case. It's basically element wise addition.
We have seen this case. Now let's look at this case. So I'll create this as A and I'll create this
as B. And now I'll try to add and show you that broadcasting. This concept is called
broadcasting in Numpy. I'll show you that broadcasting works as we expect. There is a small
catch here. Let me explain you that, okay, so I'm saying a is a numpy array, which is 00:10
2030. Right? Now it's of size four. Now, there is this new function which says NP new axis.
Now remember, this is a one dimensional array, okay? I need to convert this. I need to add a
new axis here. I need to convert this to a 2D array. So when I say a equals to a, all the rows
and NP new axis. And when I create this, what it creates now is actually, see, earlier it is a
one dimensional array. Now it gets converted to a two dimensional array, right? With four
rows and only one column. Because that's what my data is. Right. Now, if I try to print A, my
a looks like this my A from becoming a one dimensional array. So when I do this, a is one
dimensional array. But as soon as I do this, my a becomes a two dimensional array. My a
becomes a two dimensional array where I have only four elements, but in four rows and one
column. Now, since I've changed this to an array, to a 2D array, since I've changed this to a
2D array, I can do a plus B, and it will give you the result that we expect. So what we have
done here is here we have a 1D array. We converted this 1D array to a 2D array, and then to
this 2D array, we added this. Then everything works out. Now, what happens if I don't add
the 2D array? If I don't have this step? What happens if I don't have this NP new access?
What is this literally doing? It's converting from 1d array to 2D array. If I don't do this, this
addition will not work. It will say sizes don't match and hence error. Okay, so whenever you
want to do this third type of trick, whenever you want to do this third type of broadcasting,
you have to convert this 1D array to 2D array. Take the 2D array now, add it to this, and
then your whole broadcasting works as you expect. That's a small catch there. It's very, very
important. If you just try this code without doing the NP new access, and it will fail. Now
let's go to some simple array manipulations. Okay, so there is an operation called flattening,
a very important operation operator. Actually, we use it extensively in data science. So here
I'm creating an array which is 123456. It's a 2D array, of course, right? When I say a dot
ravel, r a V E l, what it does is it converts this array into this two dimensional array, into a
one dimensional array such that it first reads the first row, one, two, three, puts them here.
Next, it reads the second row and puts them here as one contiguous array. This is called
flattening because you're taking a big square and you're flattening it into a line. Right?
That's why it's called flattening. This operation is called flattening. Right. Very, very simple
operator. Nothing very fancy. Right? Similarly, we looked at transpose, so we know how
transpose works. And if you do ravel after transpose, you get a different matrix, obviously.
Right? So we understood transpose earlier itself. So no worries there. Now let's look at it. If
you want to reshape a matrix, this is fun. Now, what is our matrix? 123456. Right. 123456.
This is our matrix, and it has two rows and three columns. I'm printing the shape and I'm
printing the matrix itself. Now, if I say B equals to a dot rival, what happens? Now, my B is
123456. Now I can again do B dot reshape, two cross three. Then I will get my original a
matrix here. So ravel is a function to flatten. And reshape is another useful function, which if
you give it a flattened value, it will reshape it into other values as long as, remember, here in
a two cross three matrix, I need six values. And if there are six values here, it will work.
Otherwise it'll give you an error. Okay? Very, very simple. So reshape is also a very, very
useful function. Now comes the fun part. Now, remember what I've done. B is now nothing
but a raveled or flattened form of a, right? And b has been reshaped slightly. Now, if I say b
equal to 100, okay, so what am I doing? I'm changing this value to 100. If I print a. Now, my
A's value also is changing because what numpy does internally is numpy is storing the
whole matrix internally for both a and b the same. Internally, it's storing in the same
memory location. So whenever you change the memory location, it is not copying, it is not
copying the values of a into p. Sometimes it does. That's what you'll be slightly aware of. But
in this case, what's happening here is because numpy wants to optimize memory storage
because the data inside is still the same, right? So whether you're flattening it or whether
you're reshaping it, numpy stores that data internally in some format, okay? So it doesn't
care. So when you change your B value, your ace value. So I'm printing a and my a value also
has changed because both A and B are pointing to the same location in memory. But beware,
reshape may also return a copy sometimes. Like for example, in this case, right, you have a
numpy array of zeros, of three cross two, and now you're transposing it, reshaping it, and
things like that. When you change B, your a hasn't changed. So sometimes you have to be
very, very careful here. This is one type of mistake that happens a lot when you're reshaping
values. Okay? Now let's look at the, so we saw how to use new axes, right? To add a new axis
to your data. So now let's look at it here. I have Z is my numpy array, which is one, two,
three, which is a one dimensional array. If I want to convert this into a two dimensional
array, all I have to do is this. We saw this new axis example, right? A while ago when we
were doing broadcasting examples, right? Similarly, now comes a fun part, okay, suppose, if
I want to arrange, suppose, okay, suppose I want to construct this matrix again. It has a
shape of four cross three cross two. It's not a two dimensional matrix. It's a three
dimensional matrix. It's a three dimensional matrix with four cross three cross two, which
means it has four matrices of sizes. Three cross two. It has four matrices, okay? And each
matrix is of size, three rows and two columns. That's how we can think of three dimensional
matrices or tensors, as I told you earlier. Now I can arrange all these values. So now I'm
saying NP, arrange. How many values do I need to fill a four cross three cross two matrix? I
need four into three into two. So that's about 24 values I need. So I'm saying NP arrange 24.
So it's going to arrange all of them into one array like this, one, two, sorry, zero, one 2323.
And now I'm saying reshape them into this. So now it's reshaped them. And when it typed
the shape value, it says it has four matrices of three rows and two columns each. This is how
it exactly looks. Plotting a three dimensional matrix on paper is hard, right? But I can go and
change a specific value. For example here I'm saying that I want to change for the zero 8th
matrix for the second row and the first column, what is the value? That's what I'm trying to
answer. Or I can allocate a value here. So let's try to find out right now. Here we have four
matrices. So what is the size four, cross three, cross two, we have matrix zero, we have
matrix one, we have matrix two, we have matrix three. And each of these matrix matrices
has three rows, row zero, row one, row two and column zero and column one. So when I say
a 00:21 it goes to the zero 8th matrix, second row, second row, and first column, the value is
five. So that's what it printed. This is how you understand indexing in high dimensional
arrays or in multidimensional arrays. Okay, so again, not very hard, but you have to be
slightly careful. Now let's look at it like this, okay? Now if I say NP arrange four, what do I
get? I get 0123. Right? Now if I say a dot resize, right, when I say a dot resize, what happens
is it resizes it to eight elements, but it concatenates rest of the elements with zeros. Now
here is a type of bug that often occurs when we are using resize arrange because we do this
a lot of times in machine learning and data science. Now if I say B equals to a and if I try to
resize a now, it will not let you do it, okay, so the errors in this case would be this is all right,
right, because you're trying to resize it to a larger element. So it just adds zeros there. That's
perfectly all right. But if you have referenced or if you have another variable pointing to the
same thing, so in a you have these values, right? 0123, all zeros. Now if I try to have b also
assigned to it, and if I try to resize it, now it says cannot resize an array that references or is
referenced by another array okay, that's a value error. So you have to be careful if there are
two variables or if the two names which are pointing to the same location, resizing it will
create errors. So we learned about try catch. So we need to catch those errors. Now let's
look at some simple sorting stuff. Very, very important because we sort data a lot, actually,
in data science. So here I have my matrix, 546232. Okay? That's what I created here. Now, I
said NP sort. Access equals to one. What does access equals to one mean? Access equals to
one means row wise. Right? So I want to sort this row and I want to, when I sort this row,
what happens? I get four, five, six. When I sort this row, what do I get? Two, two, three.
Okay, that's, what is the result? Okay. Or if I want to sort it. So here I'm sorting it and
returning it to a new variable, right? If I want to sort a itself, I can just say a dot sort instead
of NP sort here. Okay? What this does is it modifies a itself. Now, after doing a dot sort, if I
say a, it will sort a and it will store the sorted value back in a itself. Okay? Now there is
something called fancy indexing, which is actually very, very interesting idea, again, used
extensively in data science. So imagine if I have an array like this. 4321. Right? This is my
array. And now I'm saying, now I'm saying NP arg sort. I'm not saying sort. So arg sort. What
it does is. So these are my initial indices. 0123. Now first it sorts this internally. Okay? When
it sorts this, what do I get? 1234. Okay, this is the sorted. But when I sorted it, what
happened? The indices changed. So what happened? The second index came here. I'm just
copying this index here. What is the index of two? Three. So the three value came here.
What is the index of three? One. Right? What is the index of? 40. So when I say NP argsort,
what I get is basically the positions of the indices after sorting, right? And now if I say aj,
now if I say aj, because j is now my arg sort, my resultant value of arcsot. So now it will get
me, first a two value. What is a two value? Now, a two value is one. Next it gets a three
because this is j, right? Because this is j, this is my vector j. Now, when I say aj, it uses these
values as indices, right? So a two will be one. What about a three? A three is two. It printed
two. Similarly, a one is three, a zero is four. So arc sort is very, very important and I
recommend you play this with larger example. Since you have this source code with you. I
recommend you play with this and understand how all of these functions are useful,
especially, especially broadcasting and argsod. Most of these numpy functions, we use them
extensively, trust me, we use them a lot in data science and machine learning.