# Intro to NumPy

NumPy is a commonly used package that we will use to manipulate a new data type called arrays. This data type is very similar to lists. One of the reasons we use the NumPy package is that it can be faster and more efficient to perform operations on NumPy arrays than lists. To use arrays, we must first import NumPy.

## **Importing NumPy** <a href="#importing-numpy" id="importing-numpy"></a>

A common way to import NumPy is to import the whole package, and to give it the abbreviation `np`.

```python
import numpy as np
```

Now that you can access the NumPy package, we will use it to create arrays.

## Arrays <a href="#arrays" id="arrays"></a>

Arrays are a data structure similar to lists. To create an array, you must input your data into a list, then you can convert it into an array by calling `np.array(list)`. If you only want to input one data piece into the array function, you can skip the list step.

![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LV1S_g7eO87zEnyt6Eg%2F-LVSD6ors_IxBPNnlyWI%2F-LVSF3FKiOLeLld-dgtW%2Fimage.png?alt=media\&token=d01a2f9a-ed03-414a-a631-ba2dae86bdcc)

### **Data Contained in Arrays** <a href="#data-contained-in-arrays" id="data-contained-in-arrays"></a>

Arrays can only hold data of the same type. If you enter different data types into an array, then it will convert them all to the same type if it can. For example, if you input an int and a float into an array, then it will convert them all to floats, so that they have the same data type.

![](https://lh3.googleusercontent.com/KnZbogDspIxbebflRofIpxGbyAtnvWIEXDJKoJ3zogMwGUDZQVA_uDXCuMvch_4-4kGRsoiIy9BFUG_Eq_a_BsomMfXZ_Nk3UHZuPaUX90qJ_8YzlmcvKCrTq9fkaxCMBPyMn_H0)

{% hint style="info" %}
The output of the array shows`dtype='<U21'` this means that the data type (dtype) within your array is string.
{% endhint %}

The items of the array must all be of the same type, because it makes storing the information simpler. In comparison to lists, arrays require less space / memory to save them.

### **Accessing Items** <a href="#accessing-items" id="accessing-items"></a>

To access the data within an array, we use a method similar to lists, but we use a function called `.item()` which must be called on an array. We call `.item()` on our array, and we input the index of the data we want to access within the parentheses.

```python
>>> h = np.array([1, "w"])
>>> h
array(['1', 'w'])​

>>> h.item(0)
'1"​

>>> h.item(1)
'w'​
>>> h.item(2)
ERROR 
### the index 2 does not exist in our array, 
### because it is not big enough
```

{% hint style="info" %}
Arrays are indexed starting at zero just like lists, meaning that the first item of our array is numbered 0, not 1. If you input an index larger than the size of the array, then it will throw an error.
{% endhint %}

### **Size** <a href="#size" id="size"></a>

Another difference between arrays and lists is that arrays have a fixed size. This means that it takes longer to add an item to an array than to a list.&#x20;

### **Adding Elements** <a href="#size" id="size"></a>

To add into an array, there are two ways we can add. We can add elements into a specific index within an array or we can add elements to the end of the array. If you only want to add to the end of an array, then the easiest way is to use the function called `np.append(...)`.&#x20;

#### `np.append()` <a href="#np-append" id="np-append"></a>

The append method lets us add on to the end of an array. It has 2 arguments. The first is the array you want to add to, and the second argument is the item(s) you want to add to the existing array.

```python
np.append(array_to_change, add_on)
```

Here are some examples of adding to the ends of arrays.

```python
>>> floats = np.array([1.0, 2.2, 3.4, 5.7])
>>> floats
array([1. , 2.2, 3.4, 5.7])​

>>> np.append(floats, 8.9)
array([1. , 2.2, 3.4, 5.7, 8.9])​

>>> floats
array([1. , 2.2, 3.4, 5.7])
```

{% hint style="info" %}
When we append to an array, the changes do not affect the original array. We have to save the changes we make by assigning the result of appending to a new array. If we assign the result to the same array, we will not have access to the original array anymore.
{% endhint %}

```python
### Defining new array
>>> f1 = np.append(floats, 8.9)
>>> f1
array([1. , 2.2, 3.4, 5.7, 8.9])

​## Still have original array
>>> floats
array([1. , 2.2, 3.4, 5.7])​

### Redefining the array
>>> floats = np.append(floats, 8.9)
>>> floats
array([1. , 2.2, 3.4, 5.7, 8.9])
```

The part that you add on to your array when using `np.append()` can be an array or list. It does not have to be a single item.

```python
>>> floats
array([1. , 2.2, 3.4, 5.7, 8.9])​

### OPTION 1
>>> np.append(floats, [10.1, 12.3, 14.5])
array([ 1. ,  2.2,  3.4,  5.7,  8.9, 10.1, 12.3, 14.5])​

### OPTION 2
>>> np.append(floats, np.array([10.1, 12.3, 14.5]))
array([ 1. ,  2.2,  3.4,  5.7,  8.9, 10.1, 12.3, 14.5])​

### Remember to save changes by defining variable
>>> floats = np.append(floats, np.array([10.1, 12.3, 14.5]))
>>> floats
array([ 1. ,  2.2,  3.4,  5.7,  8.9, 10.1, 12.3, 14.5])
```

{% hint style="warning" %}
Be careful what you add on to your array, because the type of data you enter may change all of the pieces in your array.
{% endhint %}

```python
>>> floats
array([ 1. ,  2.2,  3.4,  5.7,  8.9, 10.1, 12.3, 14.5])​

>>> np.append(floats, "str")
array(['1.0', '2.2', '3.4', '5.7', '8.9', '10.1', '12.3', '14.5', 'str'])
```

If you are not adding to the end of an array, it is best to use `np.insert(...)` which will allow you to modify the array at any index.&#x20;

#### `np.insert()` <a href="#np-insert" id="np-insert"></a>

The insert method allows us to add items into any index within an array. It has 3 arguments. The first argument is array you want to add to. The second argument is the index you want to add your data to. The index you input is the index that the value you are adding will have. If you are adding multiple values, then the first will have that index and the rest will follow. The third argument is the value(s) you want to add.

```python
np.insert(array_to_change, index_to_replace, values_being_added)
```

Here are some examples of adding a single item into an array.

```python
>>> nums = np.array([3, 10, 13, 15, 18, 20])
>>> nums
array([ 3, 10, 13, 15, 18, 20])​

>>> np.insert(nums, 0, 1)
array([ 1,  3, 10, 13, 15, 18, 20])

​>>> nums
array([ 3, 10, 13, 15, 18, 20])
```

{% hint style="info" %}
Just like`np.append(),`when we append to an array, the changes do not affect the original array, so we must define a variable.
{% endhint %}

```python
>>> n1 = np.insert(nums, 0, 1)
>>> n1
array([ 1,  3, 10, 13, 15, 18, 20])​

## Still have original array
>>> numsarray([ 3, 10, 13, 15, 18, 20])​

### Redefining the array
>>> nums = np.insert(nums, 0, 1)
>>> nums
array([ 1,  3, 10, 13, 15, 18, 20])

​### Another example
>>> nums = np.insert(nums, 1, 2)
>>> nums
array([ 1,  2,  3, 10, 13, 15, 18, 20])
```

We can add to any index in our array. In this case we can choose any number from 0 to 8. In this case, if we use 8, it is the same as ending to the end of the array.

```python
>>> np.insert(nums, 8, 30)
array([ 1,  2,  3, 10, 13, 15, 18, 20, 30])
```

The benefit to using `np.append()` instead of `np.insert()` when you are adding to the end of an array is that you do not need to know the exact size of your array with `np.append()`, while you will need the size each time you use `np.insert()`.

Let's insert multiple items into our array.

```python
>>> nums
array([ 1,  2,  3, 10, 13, 15, 18, 20])​

### OPTION 1 
>>> np.insert(nums, 8, [22, 21])
array([ 1,  2,  3, 10, 13, 15, 18, 20, 22, 21])

​### OPTION 2
>>> np.insert(nums, 8, np.array([22, 21]))
array([ 1,  2,  3, 10, 13, 15, 18, 20, 22, 21])​

### Another example
>>> np.insert(nums, 3, np.array([5, 6, 7]))
array([ 1,  2,  3,  5,  6,  7, 10, 13, 15, 18, 20])
```

{% hint style="danger" %}
Be careful what you insert into an array, because the type of data you enter may be changed to fit the types of the data already in the array. Or it will error.
{% endhint %}

```python
>>> np.insert(nums, 8, [22.2, 21.1])
array([ 1,  2,  3, 10, 13, 15, 18, 20, 22, 21])

​>>> np.insert(nums, 8, ["22.2", "21.1"])
ERROR 
```

We mentioned earlier that arrays can only hold elements of the same data type. As the example above shows, if you try to insert an integer into an existing array containing string, it will error - the data type of the element you are adding has to be the same as the data type of elements in the array.&#x20;

### **Removing Elements** <a href="#removing-elements" id="removing-elements"></a>

To delete items within an array we will use `np.delete()`. It takes in 2 arguments. The first argument is the array you want to change, and the second is the index of the item you want to remove.

```python
np.delete(array_to_change, index_to_remove)
```

Let's look at some examples.

```python
>>> arr = np.array([15, 50, 41, 49, 1, 5, 22, 30, 17, 45])
>>> arr
array([15, 50, 41, 49,  1,  5, 22, 30, 17, 45])​

>>> np.delete(arr, 1)
array([15, 41, 49,  1,  5, 22, 30, 17, 45])​

>>> arr
array([15, 50, 41, 49,  1,  5, 22, 30, 17, 45]
```

{% hint style="info" %}
Just like`np.append()`and`np.insert()`when we modify our array it does not affect original array, so we must define a variable to save the changed array.
{% endhint %}

```python
>>> arr = np.delete(arr, 1)
>>> arr
array([15, 41, 49,  1,  5, 22, 30, 17, 45])

​>>> arr = np.delete(arr, 5)
>>> arr
array([15, 41, 49,  1,  5, 30, 17, 45])
```

Now that we understand how to remove a single item, we approach removing multiple items.

```python
>>> arr
array([15, 41, 49,  1,  5, 30, 17, 45])​

### OPTION 1
>>> np.delete(arr, [1, 3, 6])
array([15, 49,  5, 30, 45])

​### OPTION 2
>>> np.delete(arr, np.array([1, 3, 6]))
array([15, 49,  5, 30, 45])
```

Now, you can create and manipulate arrays!
