<jupyter_start><jupyter_text>Source: https://www.practicaldatascience.org/html/exercises/Exercise_numpy.html Cheat Sheet: https://datacamp-community-prod.s3.amazonaws.com/e9f83f72-a81b-42c7-af44-4e35b48b20b7  Exercise 1<jupyter_code>import numpy as np
np.random.seed(21) # This guarantees the code will generate the same set of random numbers whenever executed
random_integers = np.random.randint(1,high=500000, size=(20, 5))
random_integers<jupyter_output><empty_output><jupyter_text>Exercise 2What is the average value of the second column (to two decimal places)<jupyter_code>random_integers[:,1].mean()<jupyter_output><empty_output><jupyter_text>Exercise 3What is the average value of the first 5 rows of the third and fourth columns?<jupyter_code>random_integers[:5,2:4].mean()<jupyter_output><empty_output><jupyter_text>Exercise 4Close Python. On a piece of paper, write down the final result of the following code: `Expected result is [[2 4 6], [5 7 9]]`<jupyter_code>import numpy as np
first_matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(first_matrix)
second_matrix = np.array([1, 2, 3])
print(second_matrix)
first_matrix + second_matrix<jupyter_output><empty_output><jupyter_text>Exercise 5Keep Python Closed! Write down the final result of the following code: `Expected result is [2, 4, 6] (even numbers)`<jupyter_code>my_vector = np.array([1, 2, 3, 4, 5, 6])
selection = my_vector % 2 == 0
my_vector[selection]<jupyter_output><empty_output><jupyter_text>Exercise 6Now open python and check your answers to Exercises 4 and 5.  Working with Views<jupyter_code>import numpy as np
my_array = np.array([1, 2, 3, 4])
my_array
my_slice = my_array[1:3]
my_slice
my_slice[0] = -1
my_slice
my_array<jupyter_output><empty_output><jupyter_text>This “view” behavior is entirely limited to numpy.<jupyter_code>x = [1, 2, 3]
y = x[0:2]
y[0] = "a change"
y
x<jupyter_output><empty_output><jupyter_text>When do you get a view, and when do you get a copy?Generally speaking:- **you get a view if you do a plain, basic slice of an array**, and- **the view remains a view if you edit it by modifying it using basic indexing (i.e. you use ``[]`` on the left side of the assignment operator).**Outside of those two behaviors, you will usually get a copy.<jupyter_code># this slice will get you a view:

my_array = np.array([1, 2, 3])
my_slice = my_array[1:3]
my_slice[0] = -1
my_array
# But if you use “fancy indexing” (where you pass a list when making your slice), you will NOT get a view:

my_array = np.array([1, 2, 3])
my_slice = my_array[[1,2]]
my_slice[0] = -1
my_array
# if you modify a slice without using basic indexing, you get a copy, so changes won’t propagate:

my_array = np.array([1, 2, 3])
my_slice = my_array[1:3]
my_slice = my_slice * 2
my_slice
my_array
# (If you want to do a full-array manipulation and preserve your view, always use square brackets on the left side of the assignment operator (=):

my_array = np.array([1, 2, 3])
my_slice = my_array[1:3]
my_slice[:] = my_slice * 2
my_slice
my_array<jupyter_output><empty_output><jupyter_text>**My advice on copies:** UNLESS YOU REALLY NEED A VIEW AND ARE BEING SUPER CAREFUL: don’t use views for anything but looking at data. If you ever want to modify or work with a sub-array, just make a copy to be safe. Computers are fast enough and ram is plentiful enough that for most applications, it’s almost never a problem.  Exercise 7Close your computer / laptop. Let’s try and work out a few problems in our heads to test our understanding of numpy views. Let’s start with the following array:<jupyter_code>my_array = np.array([[1, 2, 3], [4, 5, 6]])
print(my_array)
my_slice = my_array[:, 1:3]
my_slice<jupyter_output><empty_output><jupyter_text>Exercise 8Now what does my_slice look like?<jupyter_code>my_array[:, :] = my_array * 2 
my_slice<jupyter_output><empty_output><jupyter_text>Exercise 9What does my_slice look like?<jupyter_code>my_array = my_array * 2
my_slice<jupyter_output><empty_output><jupyter_text>Exercise 10Stop, open Python, and try running these examples. Were your predictions correct? If not, why not?  Exercise 11OK, let’s close Python again and go back to pen and paper. Let’s also reset my_array and start over with the following code:<jupyter_code>my_array = np.array([[1, 2, 3], [4, 5, 6]])
print(my_array)
my_slice = my_array[:, 1:3].copy()
print(my_slice)<jupyter_output>[[2 3]
 [5 6]]<jupyter_text>Now suppose we run the following code: `my_array[:, :] = my_array * 2`. What does `my_slice` look like?<jupyter_code>my_array[:, :] = my_array * 2
my_slice<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10924186148131965, 'fraction_numerical': 0.031243172383657418, 'mean_word_length': 5.925869894099849, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 52, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '655568', 'license': 'Apache-2.0', 'n_tokens_mistral': 1705, 'n_tokens_neox': 1611, 'n_words': 541, 'path': 'Practical Data Science/Practical Data Science - Duke University/3_numpy/solution.ipynb', 'repo_name': 'weynars/master-of-data-science-strategy-and-leadership', 'size': '4577'}