#!/usr/bin/env python # coding: utf-8 # Python Lists and Arrays # === # # ## Unit 4, Lecture 1 # # # *Numerical Methods and Statistics* # # ---- # #### Prof. Andrew White, Feb 8 2016 # --- # # *Suggested Reading:* # # 1. https://docs.scipy.org/doc/numpy-1.12.0/user/whatisnumpy.html # 2. https://matplotlib.org/users/pyplot_tutorial.html # List Methods # ---- # # A method is a function, but it is associated with some data. We can put a `.` after a list to call methods associated with the list. It's best to see some examples. Notice that the methods all modify the list, hence they are methods and not functions # In[45]: x = list(range(10)) print(x) x.reverse() print(x) # In[46]: x = [3,42,8,5,42,0.4,246] x.sort() print(x) x = ['A', 'C', 'B'] x.sort() print(x) # In[47]: x = list(range(4)) print(x) x.append(5) print(x) # Creating Python Lists # ==== # We saw you can explicitly declare all elements of a list, like `[5,3,2]`. You can also create lists in the following other ways: # Using the `range` function # ---- # In[48]: x = list(range(10)) x # In[49]: x = list(range(5,10)) x # In[50]: x = list(range(0,10,2)) x # In[51]: x = list(range(10,0,-1)) x # Notice that the second argument to `range` is not inclusive, even if counting downwards. # Creating Python Lists as needed # ---- # You can use the `append` function to add elements as you need them # In[52]: x = [4,3,41] x[2] = "Let's put a string here instead" x.append("And another for demonstration porpoises") print(x) # In[53]: x = [0, 1] x.append("Look! I'm putting a string in here :)") print(x) # In[141]: x = [] x.append(43) x.append('X') print(x) # In[142]: x = [] x.append([5,3,4]) x.append('ᕙ(˵ ಠ ਊ ಠ ˵)ᕗ') print(x) x.append([[54,3]]) print(x) x.append(x) print(x) print(x[-1]) # # List Assignment # # Lists can be assigned when `[]` are used on the left-hand side of the assignment operator(`=`) # You can assign a single element: # In[143]: x[-1] = 'end of list' x # You can assign a slice, but the right-hand side should be a list with the same number of elements as the slice. # In[144]: x[0:1] = ['new 0', 'new 1'] x # You can also delete items instead of assigning them: # In[145]: del x[3] x # NumPy Arrays # ==== # # Python lists are great. They can store strings, integers, or mixtures. You can even put lists into lists! NumPy arrays though are multidimensional and most scientific/engineering python libraries use them instead. **They store the same type of data in each element and cannot change size**. # In[56]: import numpy as np x = np.zeros(5) print(x) # Notice as opposed to lists, we have to state the dimension. The dimensions are passed either as a single number, like `5`, or as a tuple, like `(5,2)` creates a $5\times 2$ array. # In[57]: x = np.zeros( (5,2) ) print(x) # In[58]: x = np.zeros( (2,3,5)) print(x) # Creating NumPy Arrays # ==== # # There are many convienent methods in numpy to create arrays. You saw `zeros`. Here are others: # Ones # ---- # In[59]: x = np.ones(5) print(x) # In[60]: print(np.linspace(0,1,25)) # Notice **linspace includes the end point** and **arange does not include the endpoint**!! # **Remember:** we cannot append to NumPy arrays because their size is set once and never changed. # NumPy Functions # ==== # # Functions from the `numpy` module all take arrays as arguments, so whereas we cannot call `math.cos` on a list, we can call `np.cos` on an array. This is very useful for working with probability distributions. Numpy also treats `*`, `**` and all other arithmetic operations as per-element calculations. # In[61]: from math import pi x = np.linspace(-pi,pi,4) print(np.cos(x)) # In[62]: x = np.arange(5) print(x**2) # In[63]: x = np.arange(5) print(2 ** x) # In[64]: np.sum(x) # In[65]: np.mean(x) # In[66]: np.max(x) # This only scratches the surface of functions that take numpy arrays. There are many more that do things from computing integrals to evaluating boolean expressions to writing out files. # NumPy Methods # ==== # You can always play with these by using `TAB` in your jupyter notebook. Let's see a few. # In[67]: x = np.arange(0,10,0.1) print(x.argmax()) print(x.mean()) print(x.var()) # Plotting # ==== # # Just like we use the NumPy library for working with arrays, there is a library for plotting called Matplotlib. It's import syntax is a little funny. This is how you activiate it: # In[68]: get_ipython().run_line_magic('matplotlib', 'inline') #the line above is for jupyter notebooks only import matplotlib.pyplot as plt #we import a sub-module called pyplot and call it plt for short # In[69]: x = np.linspace(-2*pi, 2*pi, 500) y = np.sin(x) plt.plot(x,y) # To get rid of that extra line at the top, we use the `show` command. This is sort of like the difference between using `print` vs just making a variable the last line. # In[70]: x = 5 x # In[71]: x = np.linspace(-2*pi, 2*pi, 500) y = np.sin(x) plt.plot(x,y) plt.show() # Changing the Look and Feel # ---- # You may switch the look and feel of plots by using the `plt.style.use` command. You may change the size by using the `plt.figure(figsize=(4,4))` command, where you give the figure size in inches. # In[88]: plt.style.use('ggplot') plt.figure(figsize=(8,6)) x = np.linspace(-2*pi, 2*pi, 500) y = np.sin(x) plt.plot(x,y) plt.show() # In[89]: plt.style.use('fivethirtyeight') plt.figure(figsize=(4,3)) x = np.linspace(-2*pi, 2*pi, 500) y = np.sin(x) plt.plot(x,y) plt.show() # In[90]: plt.style.available # Customizing plots # ---- # You should read the matplotlib [tutorial online](http://matplotlib.org/users/pyplot_tutorial.html), but here's some basic info. # In[96]: plt.style.use('seaborn-whitegrid') plt.figure(figsize=(4,3)) plt.plot(x,y) plt.xlabel("The x-axis") plt.ylabel("The y-axis") plt.title("The title") plt.show() # In[97]: plt.plot(x,y, label="A sine wave") plt.plot(x, np.cos(x), label="A cosine wave") plt.title("A Title!") plt.legend(loc='lower left') plt.show() # In[98]: x = np.arange(10) p = 0.2 geo_p = (1 - p)**(x-1) * p plt.plot(x,geo_p,'o') #use circles plt.show() # In[99]: x = np.arange(10) p = 0.2 geo_p = (1 - p)**(x-1) * p plt.plot(x,geo_p,'yo-') #use yellow circles with dashes plt.show() # ## Specifying Color # # # One of the most common ways of specifying color is the default "color cycler". Matplotlib has a default set of *categorical* colors that represent different line types. You can specify them by using `C0` or `C1` or `C2` etc. Let's see an example of way you might want to do this: # In[113]: x = np.arange(1, 10) p = 0.2 geo_p = (1 - p)**(x-1) * p plt.plot(x, geo_p,color='C0', label='$E_1[x]$') #plot the mean as vertical line plt.axvline(x=1 / p, color='C0', linestyle='--', label='$E_1[x]$') #create a different geometric p = 0.4 geo_p = (1 - p)**(x-1) * p plt.plot(x, geo_p,color='C1', label='$P_2(x)$') #plot the mean as vertical line plt.axvline(x=1 / p, color='C1', linestyle='--', label='$E_2[x]$') #add legend, which uses the labels = .. from above plt.legend() plt.show() # Notice how I can use consistent colors for related lines in the figure. Categorical colors are for data which has no ordering. *Gradient* colors are for when a color has order. We will see those later. # For Loops # ==== # # Now that we have arrays and lists, we need need new flow statements to do something with them # In[79]: x = [4,3,24,7] for element in x: print(element) # In[80]: x = [4,3,24,7] xsum = 0 for element in x: xsum += element # <--- this means xsum = xsum + element print(xsum) # In[81]: x = [4,3,24,7] xsum = 0 for element in x: xsum += element print(xsum) # Python Tutor # ---- # # [Python Tutor](http://www.pythontutor.com/visualize.html#mode=edit) Allows you to see your code as it executes. Let's look at the last example with it. # In[82]: from IPython.display import HTML, display from IPython.core.magic import register_line_cell_magic import urllib @register_line_cell_magic def tutor(line, cell): code = urllib.parse.urlencode({"code": cell}) display(HTML(""" """.format(code))) # In[83]: get_ipython().run_cell_magic('tutor', '', "\nprod = 1\nfor i in range(5):\n prod *= i\n if prod == 0:\n prod = 1\n print('{}! = {}'.format(i, int(prod)))\n") # Python Data Types # ---- # # Let's put all we know about python data types in one place. A `data type` is something which can be assigned to a variable. For example, a floating point number or a string. # Here's a list of python data types we'll cover in the class: # # * floating point numbers # * integers # * strings # * lists # * dictionaries # * tuples # * NumPy arrays # Floating Points and Integers # ---- # In[84]: #Floating Point a = 4.4 a # In[85]: #Converting a floating point to integer a = int(4.4) a # Converting floating points is often needed when you want to slice a list. For example # In[86]: a = 'A string is a list' length = len(a) half_length = length / 2 print(a[half_length:]) # In[114]: half_length = int(length / 2) a[half_length:] # This is such a common occurence though that there is a shortcut to ensure that division results in an integer: # In[115]: 3 / 2 # In[116]: 3 // 2 # In[117]: a[len(a) // 2:] # What are the mathematical consequences of `int`? # In[118]: print(int(4.9)) # Often that's not exactly what we want, so we can use a few functions from math # In[119]: from math import floor, ceil # In[120]: print(floor(5.9)) # In[121]: print(ceil(4.0001)) # Dictionaries # ---- # Dictionaries are very similar to lists. Let's see how they work: # In[122]: d = dict() d['thingie'] = 45 d['other thingie'] = 434343 print(d['thingie']) # In[123]: print(d) # Python prints it in the format above, you can also define it using that format # In[124]: d = {'thing1': 3, 'b': 'a string'} print(d['b']) # We're learning dictionaries because they are often required for plotting and optimization. We'll see that later in this lecture # Tuples # ---- # # Tuples are just like lists, except they can't have individual elements modified. # In[125]: a = [0,1,2,3] # a list a[3] = 'fdsa' print(a) # In[126]: a = (0,1,2,3) a[3] = 'fdsa' # The most common place you'll see tuples is in creating numpy arrays # In[127]: my_tuple = (5,4) a = np.ones(my_tuple) print(a) # Notice that's the same as this: # In[128]: a = np.ones( (5,4) ) print(a) # Function Arguments # ---- # Functions are a little more complicated than just the paranthesis part. There are three things you should know about functions: # # 1. Arguments are separated by `,` # 2. Arguments may be named -> `foo(1,2,4, example=5)` # 3. You may have to pass in lists or dictionaries -> `np.ones( (5,4) )` or `foo(special_arg={'a':4, 'b':4})` # Plotting provides some examples of this. Let's see them in action # In[129]: x = np.linspace(0,10, 100) y = x**2 # In[130]: plt.plot(x, y) plt.text(2, 40, '$y = x^2$', fontdict={'fontsize': 24}) plt.show() # Most arguments are optional. For example: # In[131]: from math import log log(10) # In[132]: log(10, 10) # More about Notebooks # ==== # How to get help about functions # ---- # To get help about a particular function, type `help( fxn_name ) `. This will post it in the output. You can instead, type `fxn_name?` to get a popup with help. The most useful thing though is to type `SHIFT-TAB` to get a tooltip about a function. To get suggestions, press TAB. # What exactly is saved for a notebook? # --- # # A notebook is just a JSON file. You can open one and see this: # # ``` # { # "cell_type": "markdown", # "metadata": {}, # "source": [ # "To get help about a particular function, type `help( fxn_name ) `. This will post it in the output. You can instead, type `fxn_name?` to get a popup with help. The most useful thing though is to type `shift-tab` to get a tooltip about a function." # ] # }, # ``` # Jupyter will save checkpoints whenever you save. These can be accessed at file->revert-to-checkpoint. Pay close attention to the top messages to make sure you are saving your notebook. In an emergency, like your notebook failed to save, go to `file->download as->jupyter notebook` and it will appear in your downloads folder. # Rescuing Python Kernel # ---- # # It's easy to write code that will rek your kernel. You'll see this if the circle indicator in the top right corner is solid. If pressing interrupt (stop button) a few times doesn't work, save your notebook and then close the command line/terminal window and reopen one.